import * as Yup from 'yup';
import {
  SalesOrderProductFormValues,
  SalesOrderProductSchema,
} from '@/components/pages/marketing/form/repeater/sales-order/SalesOrderProduct.schema';
import {
  DeliveryOrderProductFormValues,
  DeliveryOrderProductSchema,
} from '@/components/pages/marketing/form/repeater/delivery-order/DeliverOrderProduct.schema';
import {
  BaseDeliveryOrder,
  BaseSalesOrder,
  Marketing,
} from '@/types/api/marketing/marketing';
import { formatDate, formatTitleCase } from '@/lib/helper';
import { getProductWarehouseOptionLabel } from '@/lib/product-warehouse';

type MarketingSchemaType = {
  customer_id: number | undefined;
  sales_person_id: number | undefined;
  sales_person:
    | {
        value: number;
        label: string;
      }
    | undefined
    | null;
  customer:
    | {
        value: number;
        label: string;
      }
    | undefined
    | null;
  so_date: string | undefined;
  notes: string | undefined;
};

type SalesOrderSchemaType = MarketingSchemaType & {
  sales_order: SalesOrderProductFormValues[];
};

type DeliveryOrderSchemaType = {
  delivery_order: DeliveryOrderProductFormValues[];
};

export const SalesOrderSchema: Yup.ObjectSchema<SalesOrderSchemaType> =
  Yup.object({
    customer_id: Yup.number().required('Customer wajib diisi!'),
    sales_person_id: Yup.number().required('Sales wajib diisi!'),
    sales_person: Yup.object({
      value: Yup.number().required(),
      label: Yup.string().required(),
    }).nullable(),
    customer: Yup.object({
      value: Yup.number().required(),
      label: Yup.string().required(),
    }).nullable(),
    so_date: Yup.string().required('Tanggal wajib diisi!'),
    notes: Yup.string().required('Catatan wajib diisi!'),
    sales_order: Yup.array()
      .of(SalesOrderProductSchema)
      .min(1, 'Produk wajib diisi!')
      .required('Produk wajib diisi!'),
  });

export const DeliveryOrderSchema: Yup.ObjectSchema<DeliveryOrderSchemaType> =
  Yup.object({
    delivery_order: Yup.array()
      .min(1, 'Pengiriman wajib diisi!')
      .required('Pengiriman wajib diisi!')
      .test(
        'at-least-one-valid-row',
        'Seluruh data pengiriman harus diisi lengkap!',
        function (items) {
          if (!items || items.length === 0) return false;

          // VALIDASI: seluruh item harus valid full
          const itemSchema = DeliveryOrderProductSchema;

          const hasValidItem = items.every((item) => {
            if (!item) return false;
            return itemSchema.isValidSync(item, { abortEarly: true });
          });

          return hasValidItem;
        }
      ),
  });

export const UpdateSalesOrderSchema = SalesOrderSchema;

export type SalesOrderFormValues = Yup.InferType<typeof SalesOrderSchema>;

export type DeliveryOrderFormValues = Yup.InferType<typeof DeliveryOrderSchema>;

// ================ Helper Function ================
export const SalesProductToFieldValues = (
  product: BaseSalesOrder
): SalesOrderProductFormValues => {
  const warehouseOption = {
    value: product.product_warehouse.warehouse.id,
    label: product.product_warehouse.warehouse.name,
  };

  return {
    id: product.id,
    vehicle_number: product.vehicle_number,
    warehouse_id: product.product_warehouse.warehouse.id,
    warehouse: warehouseOption,
    kandang_id: product.product_warehouse.warehouse.id,
    kandang: warehouseOption,
    product_warehouse: {
      value: product.product_warehouse.id,
      label: getProductWarehouseOptionLabel(product.product_warehouse),
    },
    product_warehouse_data: product.product_warehouse,
    product_warehouse_id: product.product_warehouse.id,
    unit_price: product.unit_price,
    total_weight: product.total_weight,
    qty: product.qty,
    avg_weight: product.avg_weight,
    total_price: product.total_price,
    marketing_type: product.marketing_type
      ? {
          value:
            product.marketing_type === 'AYAM' ||
            product.marketing_type === 'AYAM_PULLET'
              ? 'AYAM,AYAM_PULLET'
              : product.marketing_type,
          label: formatTitleCase(
            product.marketing_type === 'AYAM' ||
              product.marketing_type === 'AYAM_PULLET'
              ? 'AYAM'
              : product.marketing_type
          ),
        }
      : null,
    convertion_unit: product.convertion_unit
      ? {
          value: product.convertion_unit,
          label: formatTitleCase(product.convertion_unit),
        }
      : null,
    week: product.week ?? null,
    total_peti: product.total_peti,
    weight_per_convertion: product.weight_per_convertion,
    uom: product.product_warehouse.product.uom.name,
  };
};
export const DeliveryProductToFieldValues = (
  salesOrders: BaseSalesOrder[],
  delivery: BaseDeliveryOrder
): DeliveryOrderProductFormValues[] => {
  const data = delivery.deliveries.map((item) => {
    const salesOrder =
      salesOrders.find((so) => so.id === item.marketing_product_id) ??
      salesOrders.find(
        (so) => so.product_warehouse.id === item.product_warehouse.id
      );
    const warehouseOption = {
      value: item.product_warehouse.warehouse.id,
      label: item.product_warehouse.warehouse.name,
    };

    const initialSisaBerat =
      item?.total_weight &&
      salesOrder?.weight_per_convertion &&
      salesOrder?.total_peti
        ? Number(item.total_weight) -
          Number(salesOrder.weight_per_convertion) *
            Number(salesOrder.total_peti)
        : 0;

    const initialPricePerConvertion =
      item?.total_price &&
      salesOrder?.total_peti &&
      Number(salesOrder.total_peti) !== 0
        ? (Number(item.total_price) -
            initialSisaBerat * Number(item.unit_price || 0)) /
          Number(salesOrder.total_peti)
        : Number(item?.unit_price || 0);

    return {
      id: salesOrder?.id,
      unit_price: item.unit_price,
      total_weight: item.total_weight,
      qty: item.qty,
      avg_weight: item.avg_weight,
      total_price: item.total_price,
      vehicle_number: item.vehicle_number,
      delivery_date: formatDate(delivery.delivery_date, 'yyyy-MM-DD'),
      do_number: delivery.do_number,
      marketing_product_id: item.marketing_product_id ?? salesOrder?.id,
      marketing_type: salesOrder?.marketing_type
        ? {
            value:
              salesOrder?.marketing_type === 'AYAM' ||
              salesOrder?.marketing_type === 'AYAM_PULLET'
                ? 'AYAM,AYAM_PULLET'
                : salesOrder?.marketing_type,
            label: formatTitleCase(
              salesOrder?.marketing_type === 'AYAM' ||
                salesOrder?.marketing_type === 'AYAM_PULLET'
                ? 'AYAM'
                : salesOrder?.marketing_type
            ),
          }
        : null,
      convertion_unit: salesOrder?.convertion_unit
        ? {
            value: salesOrder?.convertion_unit.toLowerCase(),
            label: formatTitleCase(salesOrder?.convertion_unit),
          }
        : null,
      marketing_product: {
        id: item.marketing_product_id ?? salesOrder?.id,
        vehicle_number: item.vehicle_number,
        warehouse_id: item.product_warehouse.warehouse.id,
        warehouse: warehouseOption,
        kandang_id: item.product_warehouse.warehouse.id,
        kandang: warehouseOption,
        product_warehouse: {
          value: item.product_warehouse.id,
          label: getProductWarehouseOptionLabel(item.product_warehouse),
        },
        product_warehouse_data: item.product_warehouse,
        product_warehouse_id: item.product_warehouse.id,
        unit_price: item.unit_price,
        total_weight: item.total_weight,
        qty: item.qty,
        avg_weight: item.avg_weight,
        total_price: item.total_price,
      },
      total_peti: salesOrder?.total_peti,
      weight_per_convertion:
        item?.weight_per_convertion ?? salesOrder?.weight_per_convertion ?? 0,
      price_per_convertion: initialPricePerConvertion,
    } as DeliveryOrderProductFormValues;
  });

  return data;
};
export const mergeSOwithDO = (
  salesOrders: SalesOrderProductFormValues[],
  deliveryOrders: DeliveryOrderProductFormValues[],
  autofill?: boolean
): DeliveryOrderProductFormValues[] => {
  const hasDeliveryOrders = deliveryOrders.length > 0;

  return salesOrders.map((so) => {
    const delivery = deliveryOrders.find(
      (d) => d?.marketing_product_id === so.id
    );
    const isTelurQty =
      so.marketing_type?.value?.toLowerCase() === 'telur' &&
      so.convertion_unit?.value?.toLowerCase() === 'qty';
    const salesOrderUnitPrice =
      isTelurQty && Number(so.total_price || 0) > 0 && Number(so.qty || 0) > 0
        ? Number(so.total_price) / Number(so.qty)
        : so.unit_price;
    const salesOrderPricePerQty =
      isTelurQty &&
      Number(so.total_price || 0) > 0 &&
      Number(so.total_weight || 0) > 0
        ? Number(so.total_price) / Number(so.total_weight)
        : so.price_per_qty;

    return {
      ...so, // nilai dasar dari sales order
      marketing_product_id: so.id,
      delivery_date: delivery?.delivery_date || undefined,
      do_number: delivery?.do_number || undefined,
      vehicle_number: delivery?.vehicle_number || so.vehicle_number,
      unit_price:
        autofill && hasDeliveryOrders
          ? delivery?.unit_price
          : salesOrderUnitPrice,
      total_weight:
        autofill && hasDeliveryOrders
          ? delivery?.total_weight
          : so.total_weight,
      qty: autofill && hasDeliveryOrders ? delivery?.qty : so.qty,
      avg_weight:
        autofill && hasDeliveryOrders ? delivery?.avg_weight : so.avg_weight,
      total_price:
        autofill && hasDeliveryOrders ? delivery?.total_price : so.total_price,
      marketing_product: so, // jika ada, override
      uom: autofill && hasDeliveryOrders ? delivery?.uom : so.uom,
      weight_per_convertion:
        autofill && hasDeliveryOrders
          ? delivery?.weight_per_convertion
          : so.weight_per_convertion,
      price_per_convertion:
        autofill && hasDeliveryOrders
          ? delivery?.price_per_convertion
          : so.price_per_convertion,
      convertion_unit:
        autofill && hasDeliveryOrders
          ? delivery?.convertion_unit
          : so.convertion_unit,
      marketing_type:
        autofill && hasDeliveryOrders
          ? delivery?.marketing_type
          : so.marketing_type,
      total_peti:
        autofill && hasDeliveryOrders ? delivery?.total_peti : so.total_peti,
      price_per_qty:
        autofill && hasDeliveryOrders
          ? delivery?.price_per_qty
          : salesOrderPricePerQty,
      sisa_berat:
        autofill && hasDeliveryOrders ? delivery?.sisa_berat : so.sisa_berat,
      price_sisa_berat:
        autofill && hasDeliveryOrders
          ? delivery?.price_sisa_berat
          : so.price_sisa_berat,
      week: autofill && hasDeliveryOrders ? delivery?.week : so.week,
    } as DeliveryOrderProductFormValues;
  });
};

export const getFilledMarketingFormInitialValues = (
  marketing: Marketing
): SalesOrderFormValues & DeliveryOrderFormValues => {
  return {
    customer_id: marketing.customer.id,
    sales_person_id: marketing.sales_person.id,
    sales_person: {
      value: marketing.sales_person.id,
      label: marketing.sales_person.name,
    },
    customer: {
      value: marketing.customer.id,
      label: marketing.customer.name,
    },
    so_date: formatDate(marketing.so_date, 'yyyy-MM-DD'),
    notes: marketing.notes,
    sales_order: marketing.sales_order.map((so) =>
      SalesProductToFieldValues(so)
    ),
    delivery_order: mergeSOwithDO(
      marketing.sales_order?.map(SalesProductToFieldValues) ?? [],
      marketing.delivery_order?.flatMap((delivery) =>
        DeliveryProductToFieldValues(marketing.sales_order, delivery)
      ) ?? [],
      marketing.latest_approval.step_number > 1
    ),
  };
};

export const getPricePerConvertion = (
  totalPrice: number,
  weightPerConvertion: number,
  totalPeti: number
) => {
  return totalPrice / (weightPerConvertion * totalPeti);
};
