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 LABOR_DEFAULT_RATE = {
  corporate: 100,
  residential: 85,
} as const;

const roundMoney = (value: number) => Math.round(value * 100) / 100;

const addLaborSchema = z
  .object({
    laborStyle: z.enum(["field", "tech"]),
    customerType: z.enum(["corporate", "residential"]).optional(),
    hours: z.number().positive().optional(),
    rate: z.number().min(0).optional(),
    ppu: z.number().min(0).optional(),
    cpu: z.number().min(0).optional(),
    taxable: z.boolean().optional(),
    taxableFlag: z.boolean().optional(),
    description: z.string().min(1).optional(),
    customerDescription: z.string().min(1).optional(),
    procurementNotes: z.string().optional(),
    productNarrative: z.string().optional(),
  })
  .strict();

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

    const laborCatalog = await procurement.fetchLaborCatalogItems();
    const selectedCatalog =
      input.laborStyle === "tech" ? laborCatalog.tech : laborCatalog.field;

    const customerType = input.customerType ?? "corporate";
    const defaultRate = LABOR_DEFAULT_RATE[customerType];
    const quantity = input.hours ?? 1;
    const ppu = input.ppu ?? input.rate ?? defaultRate;
    const cpu = input.cpu ?? roundMoney(ppu * 0.5);
    const taxableFlag =
      input.taxable ?? input.taxableFlag ?? selectedCatalog.salesTaxable;

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

    const payload = {
      ...(input.procurementNotes || input.productNarrative
        ? {
            customFields: [
              ...(input.procurementNotes
                ? [
                    makeCustomField(
                      "Procurement Notes",
                      input.procurementNotes,
                      29,
                    ),
                  ]
                : []),
              ...(input.productNarrative
                ? [
                    makeCustomField(
                      "Product Narrative",
                      input.productNarrative,
                      46,
                    ),
                  ]
                : []),
            ],
          }
        : {}),
      catalogItem: { id: selectedCatalog.cwCatalogId },
      description:
        input.description ??
        selectedCatalog.name ??
        selectedCatalog.identifier ??
        `${input.laborStyle.toUpperCase()} Labor`,
      customerDescription: input.customerDescription,
      quantity,
      price: ppu,
      cost: cpu,
      taxableFlag,
      dropshipFlag: false,
      billableOption: "Billable",
    };

    const opportunity = await opportunities.fetchRecord(identifier);
    const [created] = await opportunity.addProcurementProducts(payload);

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

    const response = apiResponse.created(
      "Labor added to opportunity successfully!",
      {
        id: created?.id ?? null,
        forecastDetailId: created?.forecastDetailId ?? null,
        laborStyle: input.laborStyle,
        customerType,
        catalogItem: {
          id: selectedCatalog.cwCatalogId,
          identifier: selectedCatalog.identifier,
          name: selectedCatalog.name,
        },
        description: created?.description ?? payload.description,
        customerDescription:
          created?.customerDescription ?? input.customerDescription ?? null,
        quantity: created?.quantity ?? quantity,
        rate: ppu,
        ppu,
        cpu,
        revenue: roundMoney((created?.quantity ?? quantity) * ppu),
        cost: roundMoney((created?.quantity ?? quantity) * cpu),
        taxableFlag: created?.taxableFlag ?? taxableFlag,
        procurementNotes,
        productNarrative,
      },
    );

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