import { createRoute } from "../../../../../modules/api-utils/createRoute";
import { opportunities } from "../../../../../managers/opportunities";
import { procurement } from "../../../../../managers/procurement";
import { apiResponse } from "../../../../../modules/api-utils/apiResponse";
import { ContentfulStatusCode } from "hono/utils/http-status";
import { authMiddleware } from "../../../../middleware/authorization";
import { z } from "zod";

const specialOrderItemSchema = z
  .object({
    desc: z.string().min(1),
    customerDesc: z.string().min(1).optional(),
    qty: z.number().positive().optional(),
    price: z.number(),
    cost: z.number().optional(),
    taxable: z.boolean().optional(),
    taxableFlag: z.boolean().optional(),
    procurementNotes: z.string().optional(),
    productNarrative: z.string().optional(),
  })
  .strict();

const addSpecialOrderSchema = z.union([
  specialOrderItemSchema,
  z
    .array(specialOrderItemSchema)
    .min(1, "At least one special-order product is required"),
]);

/* POST /v1/sales/opportunities/opportunity/:identifier/products/special-order */
export default createRoute(
  "post",
  ["/opportunities/opportunity/:identifier/products/special-order"],
  async (c) => {
    const identifier = c.req.param("identifier");
    const body = await c.req.json();

    const validated = addSpecialOrderSchema.parse(body);
    const inputItems = Array.isArray(validated) ? validated : [validated];
    const specialOrderCatalogItem =
      await procurement.fetchItem("SPECIAL ORDER");

    const makeCustomField = (
      caption: string,
      value: string,
      fieldId: number,
    ) => ({
      id: fieldId,
      caption,
      type: "Text",
      entryMethod: "EntryField",
      value,
    });

    const normalizedItems = inputItems.map((item) => ({
      ...(item.procurementNotes || item.productNarrative
        ? {
            customFields: [
              ...(item.procurementNotes
                ? [
                    makeCustomField(
                      "Procurement Notes",
                      item.procurementNotes,
                      29,
                    ),
                  ]
                : []),
              ...(item.productNarrative
                ? [
                    makeCustomField(
                      "Product Narrative",
                      item.productNarrative,
                      46,
                    ),
                  ]
                : []),
            ],
          }
        : {}),
      catalogItem: { id: specialOrderCatalogItem.cwCatalogId },
      description: item.desc,
      customerDescription: item.customerDesc,
      quantity: item.qty ?? 1,
      price: item.price,
      cost: item.cost,
      taxableFlag:
        item.taxable ??
        item.taxableFlag ??
        specialOrderCatalogItem.salesTaxable,
      dropshipFlag: false,
      billableOption: "Billable",
    }));

    const opportunity = await opportunities.fetchRecord(identifier);
    const created = await opportunity.addProcurementProducts(normalizedItems);

    const serialized = created.map((item: any) => {
      const fields = Array.isArray(item?.customFields) ? item.customFields : [];
      const procurementNotes =
        fields.find((f: any) => f?.id === 29)?.value ?? null;
      const productNarrative =
        fields.find((f: any) => f?.id === 46)?.value ?? null;

      return {
        id: item?.id ?? null,
        forecastDetailId: item?.forecastDetailId ?? null,
        description: item?.description ?? null,
        productDescription: item?.description ?? null,
        customerDescription: item?.customerDescription ?? null,
        quantity: item?.quantity ?? null,
        price: item?.price ?? null,
        revenue: item?.price ?? null,
        cost: item?.cost ?? null,
        taxableFlag: item?.taxableFlag ?? null,
        specialOrderFlag: item?.specialOrderFlag ?? null,
        procurementNotes,
        productNarrative,
      };
    });

    const isBatch = Array.isArray(body);
    const response = apiResponse.created(
      isBatch
        ? `${created.length} special-order product(s) added successfully!`
        : "Special-order product added successfully!",
      isBatch ? serialized : serialized[0]!,
    );

    return c.json(response, response.status as ContentfulStatusCode);
  },
  authMiddleware({
    permissions: ["sales.opportunity.product.add.specialOrder"],
  }),
);
