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';

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',
        'Minimal harus  ada satu baris pengiriman yang lengkap diisi!',
        function (items) {
          if (!items || items.length === 0) return false;

          // VALIDASI: minimal 1 item valid full
          const itemSchema = DeliveryOrderProductSchema;

          const hasValidItem = items.some((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 => {
  return {
    id: product.id,
    vehicle_number: product.vehicle_number,
    kandang_id: product.product_warehouse.warehouse.id,
    kandang: {
      value: product.product_warehouse.warehouse.id,
      label: product.product_warehouse.warehouse.name,
    },
    product_warehouse: {
      value: product.product_warehouse.id,
      label: product.product_warehouse.product.name,
    },
    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,
          label: formatTitleCase(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 soId = salesOrders.find(
      (so) => so.product_warehouse.id === item.product_warehouse.id
    )?.id;
    return {
      id: soId,
      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: soId,
      marketing_product: {
        id: soId,
        vehicle_number: item.vehicle_number,
        kandang_id: item.product_warehouse.warehouse.id,
        kandang: {
          value: item.product_warehouse.warehouse.id,
          label: item.product_warehouse.warehouse.name,
        },
        product_warehouse: {
          value: item.product_warehouse.id,
          label: item.product_warehouse.product.name,
        },
        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,
      },
    } as DeliveryOrderProductFormValues;
  });
  return data;
};
export const mergeSOwithDO = (
  salesOrders: SalesOrderProductFormValues[],
  deliveryOrders: DeliveryOrderProductFormValues[],
  autofill?: boolean
): DeliveryOrderProductFormValues[] => {
  return salesOrders.map((so) => {
    const delivery = deliveryOrders.find(
      (d) => d?.marketing_product_id === so.id
    );

    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 ? so.unit_price : delivery?.unit_price,
      total_weight: autofill ? so.total_weight : delivery?.total_weight,
      qty: autofill ? so.qty : delivery?.qty,
      avg_weight: autofill ? so.avg_weight : delivery?.avg_weight,
      total_price: autofill ? so.total_price : delivery?.total_price,
      marketing_product: so, // jika ada, override
      uom: autofill ? so.uom : delivery?.uom,
      weight_per_convertion: autofill
        ? so.weight_per_convertion
        : delivery?.weight_per_convertion,
      price_per_convertion: autofill
        ? so.price_per_convertion
        : delivery?.price_per_convertion,
      convertion_unit: autofill
        ? so.convertion_unit
        : delivery?.convertion_unit,
      marketing_type: autofill ? so.marketing_type : delivery?.marketing_type,
      total_peti: autofill ? so.total_peti : delivery?.total_peti,
      price_per_qty: autofill ? so.price_per_qty : delivery?.price_per_qty,
      sisa_berat: autofill ? so.sisa_berat : delivery?.sisa_berat,
      price_sisa_berat: autofill
        ? so.price_sisa_berat
        : delivery?.price_sisa_berat,
      week: autofill ? so.week : delivery?.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);
};
