import { createRoute } from "../../../../../modules/api-utils/createRoute";
import { opportunities } from "../../../../../managers/opportunities";
import { apiResponse } from "../../../../../modules/api-utils/apiResponse";
import { ContentfulStatusCode } from "hono/utils/http-status";
import { authMiddleware } from "../../../../middleware/authorization";
import { z } from "zod";
import { cwMembers } from "../../../../../managers/cwMembers";
import {
  createWorkflowActivity,
  resolveQuoteParentActivityCwId,
  OptimaType,
  OpportunityStatus,
} from "../../../../../workflows/wf.opportunity";

/** Status IDs that do NOT require the backgenerate permission. */
const STANDARD_GENERATE_STATUSES = new Set<number>([
  OpportunityStatus.New,
  OpportunityStatus.Active,
]);

const commitQuoteSchema = z
  .object({
    lineItemPricing: z.boolean().optional(),
    includeQuoteNarrative: z.boolean().optional(),
    includeItemNarratives: z.boolean().optional(),
    separateRecurringServices: z.boolean().optional(),
  })
  .strict()
  .optional();

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

    const opts = commitQuoteSchema.parse(body);

    const item = await opportunities.fetchRecord(identifier);
    const user = c.get("user");

    // If the opportunity is in the Optima workflow and NOT in a standard generate state
    // (New or Active), require the backgenerate permission.
    if (
      item.stageName === "Optima" &&
      item.statusCwId != null &&
      !STANDARD_GENERATE_STATUSES.has(item.statusCwId)
    ) {
      const canBackGenerate = await user.hasPermission(
        "sales.opportunity.quote.commit.backgenerate",
      );
      if (!canBackGenerate) {
        return c.json(
          {
            successful: false,
            message:
              "Generating a quote in this workflow state requires the 'sales.opportunity.quote.commit.backgenerate' permission.",
          },
          403,
        );
      }
    }

    const quote = await item.commitQuote(opts ?? {}, user);

    // Create a workflow activity for the generated quote
    try {
      let cwMemberId: number | null = null;

      if (user.cwIdentifier) {
        const cwMember = await cwMembers.fetch(user.cwIdentifier);
        cwMemberId = cwMember.cwMemberId;
      }

      if (cwMemberId) {
        const parentActivityCwId = await resolveQuoteParentActivityCwId(
          item.cwOpportunityId,
        );

        await createWorkflowActivity({
          name: `[Workflow] Quote generated — ${item.name}`,
          opportunityCwId: item.cwOpportunityId,
          companyCwId: item.companyCwId,
          assignToCwMemberId: cwMemberId,
          notes: `Quote "${quote.quoteFileName}" generated.`,
          optimaType: OptimaType.QuoteGenerated,
          quoteId: quote.id,
          parentActivityCwId,
        });
      }
    } catch (activityErr) {
      console.error(
        "[Quote Commit] Failed to create workflow activity:",
        activityErr,
      );
      // Don't fail the quote commit if the activity fails
    }

    const response = apiResponse.created(
      "Quote committed successfully!",
      quote.toJson({ includeRegenData: true, includeRegenParams: true }),
    );
    return c.json(response, response.status as ContentfulStatusCode);
  },
  authMiddleware({ permissions: ["sales.opportunity.quote.commit"] }),
);
