import type {
  LotTransformationDetail,
  LotTransformationListItem
} from "@/types/lot-transformation";

type DecimalLike = { toNumber(): number };

type TransformationListSerializable = {
  id: bigint;
  transformationNo: string;
  transformationType: string;
  transformationDate: Date;
  status: string;
  inputs: Array<{ qtyUsed: DecimalLike }>;
  outputs: Array<{ qtyProduced: DecimalLike }>;
};

type TransformationDetailSerializable = {
  id: bigint;
  transformationNo: string;
  transformationType: string;
  transformationDate: Date;
  status: string;
  remainderMode: string | null;
  remainderQty: DecimalLike | null;
  processingLossMode: string | null;
  processingLossQty: DecimalLike | null;
  notes: string | null;
  inputs: Array<{
    id: bigint;
    qtyUsed: DecimalLike;
    unitCostSnapshot: DecimalLike;
    notes: string | null;
    sourceLot: {
      id: bigint;
      lotCode: string;
      availableQty: DecimalLike;
      unit: { code: string };
      warehouse: { name: string };
      warehouseLocation: { name: string } | null;
      grade: { name: string } | null;
    };
  }>;
  outputs: Array<{
    id: bigint;
    qtyProduced: DecimalLike;
    notes: string | null;
    resultLot: {
      id: bigint;
      lotCode: string;
      availableQty: DecimalLike;
      unitCost: DecimalLike;
      status: string;
      unit: { code: string };
      warehouse: { name: string };
      warehouseLocation: { name: string } | null;
      grade: { name: string } | null;
    };
  }>;
};

export function serializeLotTransformationListItem(
  item: TransformationListSerializable
): LotTransformationListItem {
  return {
    id: item.id.toString(),
    transformation_no: item.transformationNo,
    transformation_type: item.transformationType,
    transformation_date: item.transformationDate.toISOString(),
    status: item.status,
    input_count: item.inputs.length,
    output_count: item.outputs.length,
    total_input_qty: item.inputs.reduce((sum, row) => sum + row.qtyUsed.toNumber(), 0),
    total_output_qty: item.outputs.reduce((sum, row) => sum + row.qtyProduced.toNumber(), 0)
  };
}

export function serializeLotTransformationDetail(
  item: TransformationDetailSerializable
): LotTransformationDetail {
  return {
    id: item.id.toString(),
    transformation_no: item.transformationNo,
    transformation_type: item.transformationType,
    transformation_date: item.transformationDate.toISOString(),
    status: item.status,
    remainder_mode: item.remainderMode,
    remainder_qty: item.remainderQty?.toNumber() ?? null,
    processing_loss_mode: item.processingLossMode,
    processing_loss_qty: item.processingLossQty?.toNumber() ?? null,
    notes: item.notes,
    inputs: item.inputs.map((input) => {
      return {
        id: input.id.toString(),
        source_lot: {
          id: input.sourceLot.id.toString(),
          lot_code: input.sourceLot.lotCode,
          grade: input.sourceLot.grade?.name ?? "-",
          available_qty: input.sourceLot.availableQty.toNumber(),
          unit_code: input.sourceLot.unit.code,
          warehouse: input.sourceLot.warehouse.name,
          location: input.sourceLot.warehouseLocation?.name ?? null
        },
        qty_used: input.qtyUsed.toNumber(),
        unit_cost_snapshot: input.unitCostSnapshot.toNumber(),
        notes: input.notes
      };
    }),
    outputs: item.outputs.map((output) => {
      return {
        id: output.id.toString(),
        result_lot: {
          id: output.resultLot.id.toString(),
          lot_code: output.resultLot.lotCode,
          grade: output.resultLot.grade?.name ?? "-",
          available_qty: output.resultLot.availableQty.toNumber(),
          unit_code: output.resultLot.unit.code,
          warehouse: output.resultLot.warehouse.name,
          location: output.resultLot.warehouseLocation?.name ?? null,
          status: output.resultLot.status
        },
        qty_produced: output.qtyProduced.toNumber(),
        unit_cost: output.resultLot.unitCost.toNumber(),
        notes: output.notes
      };
    })
  };
}
