import * as Yup from 'yup';
import { TransferToLaying } from '@/types/api/production/transfer-to-laying';
import { TransferToLayingApi } from '@/services/api/production/transfer-to-laying';
import { formatDate, formatNumber } from '@/lib/helper';

type TransferToLayingFormSchemaType = {
  transfer_date?: string;
  flockSource?: {
    value: number;
    label: string;
  };
  flockDestination?: {
    value: number;
    label: string;
  };

  totalQuantity?: number | string;
  maxTotalQuantity?: number; // original cap (hidden), helper

  flockSourceKandangs: {
    kandang: {
      value: number;
      label: string;
    };
    quantity: number | string; // editable
    maxQuantity?: number; // original cap (hidden), helper
  }[];

  flockDestinationKandangs: {
    kandang: {
      value: number;
      label: string;
    };
    quantity: number | string; // editable
    maxQuantity?: number; // original cap (hidden), helper
  }[];

  reason?: string;
};

export const TransferToLayingFormSchema: Yup.ObjectSchema<TransferToLayingFormSchemaType> =
  Yup.object({
    transfer_date: Yup.string().required('Tanggal transfer wajib diisi!'),

    flockSource: Yup.object({
      value: Yup.number().min(1).required(),
      label: Yup.string().required(),
    }).required('Flock asal wajib diisi!'),

    flockDestination: Yup.object({
      value: Yup.number().min(1).required(),
      label: Yup.string().required(),
    }).required('Flock tujuan wajib diisi!'),

    totalQuantity: Yup.number()
      .min(0, 'Jumlah transfer minimal 0')
      .max(
        Yup.ref('maxTotalQuantity'),
        ({ max }) =>
          `Kuantitas melebihi kapasitas kandang tujuan. Kuantitas maksimal ${formatNumber(max, 'en-US')}!`
      )
      .required('Jumlah transfer wajib diisi!'),

    maxTotalQuantity: Yup.number()
      .min(0, 'Jumlah transfer minimal 0')
      .required('Jumlah transfer wajib diisi!'),

    flockSourceKandangs: Yup.array()
      .of(
        Yup.object({
          kandang: Yup.object({
            value: Yup.number().min(1).required(),
            label: Yup.string().required(),
          }).required('Kandang wajib diisi!'),

          quantity: Yup.number()
            .min(0, 'Kuantitas minimal 0!')
            .max(
              Yup.ref('maxQuantity'),
              ({ max }) => `Kuantitas maksimal ${formatNumber(max, 'en-US')}!`
            )
            .required('Kuantitas wajib diisi!'),

          maxQuantity: Yup.number().min(0).required(), // internal helper field
        })
      )
      .min(1, 'Minimal 1 kandang terisi!')
      .required('Kandang wajib diisi!'),

    flockDestinationKandangs: Yup.array()
      .of(
        Yup.object({
          kandang: Yup.object({
            value: Yup.number().min(1).required(),
            label: Yup.string().required(),
          }).required('Kandang wajib diisi!'),

          quantity: Yup.number()
            .min(0, 'Kuantitas minimal 0!')
            .max(
              Yup.ref('maxQuantity'),
              ({ max }) =>
                `Kuantitas melebihi kapasitas kandang tujuan. Maks: ${formatNumber(max, 'en-US')}!`
            )
            .required('Kuantitas wajib diisi!'),

          maxQuantity: Yup.number().min(0).required(), // internal helper field
        })
      )
      .min(1, 'Minimal 1 kandang terisi!')
      .required('Kandang wajib diisi!'),

    reason: Yup.string().required('Alasan transfer wajib diisi!'),
  });

export const UpdateTransferToLayingFormSchema = TransferToLayingFormSchema;

export type TransferToLayingFormValues = Yup.InferType<
  typeof TransferToLayingFormSchema
>;

export const getTransferToLayingFormInitialValues = (
  initialValues?: TransferToLaying
): TransferToLayingFormValues => {
  return {
    transfer_date: initialValues?.transfer_date
      ? formatDate(initialValues.transfer_date, 'YYYY-MM-DD')
      : '',
    flockSource: initialValues?.from_project_flock
      ? {
          value: initialValues?.from_project_flock.id,
          label: initialValues?.from_project_flock.flock_name,
        }
      : undefined,
    flockDestination: initialValues?.to_project_flock
      ? {
          value: initialValues?.to_project_flock.id,
          label: initialValues?.to_project_flock.flock_name,
        }
      : undefined,
    totalQuantity:
      initialValues?.usage_qty ?? initialValues?.pending_usage_qty ?? '',

    flockSourceKandangs: initialValues?.sources
      ? initialValues.sources.map((sourceKandang) => ({
          kandang: {
            value: sourceKandang.source_project_flock_kandang.id,
            label: sourceKandang.source_project_flock_kandang.kandang.name,
          },
          quantity: sourceKandang.qty,
        }))
      : [],

    flockDestinationKandangs: initialValues?.targets
      ? initialValues.targets.map((targetKandang) => ({
          kandang: {
            value: targetKandang.target_project_flock_kandang.id,
            label: targetKandang.target_project_flock_kandang.kandang.name,
          },
          quantity: targetKandang.qty,
        }))
      : [],

    reason: initialValues?.notes ?? undefined,
  };
};

export const getFilledTransferToLayingFormInitialValues = async (
  initialValues?: TransferToLaying
): Promise<TransferToLayingFormValues> => {
  const mappedFlockSourceKandangsAvailableQty =
    await TransferToLayingApi.getMappedFlockKandangsAvailability(
      initialValues?.from_project_flock.id as number
    );

  const mappedFlockDestinationKandangsMaxTargetQty =
    await TransferToLayingApi.getMappedFlockKandangsMaxTargetQty(
      initialValues?.to_project_flock.id as number
    );

  const formattedFlockSourceKandangs = initialValues?.sources
    ? initialValues.sources.map((sourceKandang) => ({
        kandang: {
          value: sourceKandang.source_project_flock_kandang.id,
          label: sourceKandang.source_project_flock_kandang.kandang.name,
        },
        quantity: sourceKandang.qty,
        maxQuantity:
          (mappedFlockSourceKandangsAvailableQty &&
            mappedFlockSourceKandangsAvailableQty[
              sourceKandang.source_project_flock_kandang.id
            ].available_qty) ??
          0,
      }))
    : [];

  let maxTotalQuantity = 0;
  formattedFlockSourceKandangs.forEach((item) => {
    maxTotalQuantity += item.quantity;
  });

  const formattedFlockDestinationKandangs = initialValues?.targets
    ? initialValues.targets.map((targetKandang) => {
        return {
          kandang: {
            value: targetKandang.target_project_flock_kandang.id,
            label: targetKandang.target_project_flock_kandang.kandang.name,
          },
          quantity: targetKandang.qty,

          maxQuantity:
            (mappedFlockDestinationKandangsMaxTargetQty &&
              mappedFlockDestinationKandangsMaxTargetQty[
                targetKandang.target_project_flock_kandang.id
              ].max_target_qty) ??
            0,
        };
      })
    : [];

  return {
    transfer_date: initialValues?.transfer_date
      ? formatDate(initialValues.transfer_date, 'YYYY-MM-DD')
      : '',
    flockSource: initialValues?.from_project_flock
      ? {
          value: initialValues?.from_project_flock.id,
          label: initialValues?.from_project_flock.flock_name,
        }
      : undefined,
    flockDestination: initialValues?.to_project_flock
      ? {
          value: initialValues?.to_project_flock.id,
          label: initialValues?.to_project_flock.flock_name,
        }
      : undefined,
    totalQuantity:
      initialValues?.usage_qty ?? initialValues?.pending_usage_qty ?? undefined,
    maxTotalQuantity: maxTotalQuantity,

    flockSourceKandangs: formattedFlockSourceKandangs,

    flockDestinationKandangs: formattedFlockDestinationKandangs,

    reason: initialValues?.notes ?? undefined,
  };
};
