import { createRoute } from "../../../../../modules/api-utils/createRoute";
import { apiResponse } from "../../../../../modules/api-utils/apiResponse";
import { ContentfulStatusCode } from "hono/utils/http-status";
import { authMiddleware } from "../../../../middleware/authorization";
import { opportunities } from "../../../../../managers/opportunities";
import {
  OpportunityStatus,
  StatusIdToKey,
  WorkflowPermissions,
  type OpportunityStatusKey,
} from "../../../../../workflows/wf.opportunity";
import {
  checkColdStatus,
  type ColdCheckResult,
} from "../../../../../modules/algorithms/algo.coldThreshold";

// ═══════════════════════════════════════════════════════════════════════════
// ACTION AVAILABILITY MAP
// ═══════════════════════════════════════════════════════════════════════════

/**
 * Per-status list of actions the user can invoke.
 *
 * Each entry describes the action key, a human-readable label, the
 * expected target status(es), whether a note is required, and any
 * permission gate beyond the base workflow permission.
 */
interface AvailableAction {
  action: string;
  label: string;
  targetStatuses: { key: OpportunityStatusKey; id: number }[];
  requiresNote: boolean;
  requiresPermission: string | null;
  /** Extra payload fields that can/must be provided. */
  payloadHints?: Record<string, string>;
}

const ACTION_MAP: Record<number, AvailableAction[]> = {
  [OpportunityStatus.PendingNew]: [
    {
      action: "acceptNew",
      label: "Accept / Set Up Opportunity",
      targetStatuses: [{ key: "New", id: OpportunityStatus.New }],
      requiresNote: false,
      requiresPermission: null,
    },
  ],

  [OpportunityStatus.New]: [
    {
      action: "markReadyToSend",
      label: "Mark Ready to Send",
      targetStatuses: [
        { key: "ReadyToSend", id: OpportunityStatus.ReadyToSend },
      ],
      requiresNote: false,
      requiresPermission: null,
    },
    {
      action: "sendQuote",
      label: "Send Quote (skip review)",
      targetStatuses: [{ key: "QuoteSent", id: OpportunityStatus.QuoteSent }],
      requiresNote: false,
      requiresPermission: null,
      payloadHints: {
        quoteConfirmed: "boolean — mark confirmed simultaneously",
        won: "boolean — immediate win",
        lost: "boolean — immediate rejection",
        needsRevision: "boolean — needs revision",
      },
    },
    {
      action: "requestReview",
      label: "Send to Internal Review",
      targetStatuses: [
        { key: "InternalReview", id: OpportunityStatus.InternalReview },
      ],
      requiresNote: true,
      requiresPermission: null,
    },
    {
      action: "cancel",
      label: "Cancel Opportunity",
      targetStatuses: [{ key: "Canceled", id: OpportunityStatus.Canceled }],
      requiresNote: true,
      requiresPermission: WorkflowPermissions.CANCEL,
    },
  ],

  [OpportunityStatus.InternalReview]: [
    {
      action: "reviewDecision",
      label: "Approve (move to Ready to Send)",
      targetStatuses: [
        { key: "ReadyToSend", id: OpportunityStatus.ReadyToSend },
      ],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { decision: '"approve"' },
    },
    {
      action: "reviewDecision",
      label: "Reject (move to Pending Revision)",
      targetStatuses: [
        { key: "PendingRevision", id: OpportunityStatus.PendingRevision },
      ],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { decision: '"reject"' },
    },
    {
      action: "reviewDecision",
      label: "Send Quote (reviewer sends directly)",
      targetStatuses: [{ key: "QuoteSent", id: OpportunityStatus.QuoteSent }],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { decision: '"send"' },
    },
    {
      action: "reviewDecision",
      label: "Cancel from Review",
      targetStatuses: [{ key: "Canceled", id: OpportunityStatus.Canceled }],
      requiresNote: true,
      requiresPermission: WorkflowPermissions.CANCEL,
      payloadHints: { decision: '"cancel"' },
    },
  ],

  [OpportunityStatus.ReadyToSend]: [
    {
      action: "sendQuote",
      label: "Send Quote to Customer",
      targetStatuses: [{ key: "QuoteSent", id: OpportunityStatus.QuoteSent }],
      requiresNote: false,
      requiresPermission: null,
      payloadHints: {
        quoteConfirmed: "boolean — mark confirmed simultaneously",
        won: "boolean — immediate win",
        lost: "boolean — immediate rejection",
        needsRevision: "boolean — needs revision",
      },
    },
  ],

  [OpportunityStatus.PendingSent]: [
    {
      action: "markReadyToSend",
      label: "Mark Ready to Send",
      targetStatuses: [
        { key: "ReadyToSend", id: OpportunityStatus.ReadyToSend },
      ],
      requiresNote: false,
      requiresPermission: null,
    },
    {
      action: "sendQuote",
      label: "Send Quote to Customer",
      targetStatuses: [{ key: "QuoteSent", id: OpportunityStatus.QuoteSent }],
      requiresNote: false,
      requiresPermission: null,
      payloadHints: {
        quoteConfirmed: "boolean — mark confirmed simultaneously",
        won: "boolean — immediate win",
        lost: "boolean — immediate rejection",
        needsRevision: "boolean — needs revision",
      },
    },
  ],

  [OpportunityStatus.PendingRevision]: [
    {
      action: "beginRevision",
      label: "Begin Revision",
      targetStatuses: [{ key: "Active", id: OpportunityStatus.Active }],
      requiresNote: false,
      requiresPermission: null,
    },
  ],

  [OpportunityStatus.QuoteSent]: [
    {
      action: "confirmQuote",
      label: "Confirm Quote Receipt",
      targetStatuses: [
        { key: "ConfirmedQuote", id: OpportunityStatus.ConfirmedQuote },
      ],
      requiresNote: false,
      requiresPermission: null,
    },
    {
      action: "finalize",
      label: "Mark as Won",
      targetStatuses: [
        { key: "Won", id: OpportunityStatus.Won },
        { key: "PendingWon", id: OpportunityStatus.PendingWon },
      ],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { outcome: '"won"' },
    },
    {
      action: "finalize",
      label: "Mark as Lost",
      targetStatuses: [
        { key: "PendingLost", id: OpportunityStatus.PendingLost },
      ],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { outcome: '"lost"' },
    },
    {
      action: "resendQuote",
      label: "Revise & Re-send (back to Active)",
      targetStatuses: [{ key: "Active", id: OpportunityStatus.Active }],
      requiresNote: false,
      requiresPermission: null,
      payloadHints: { needsRevision: "true" },
    },
  ],

  [OpportunityStatus.ConfirmedQuote]: [
    {
      action: "finalize",
      label: "Mark as Won",
      targetStatuses: [
        { key: "Won", id: OpportunityStatus.Won },
        { key: "PendingWon", id: OpportunityStatus.PendingWon },
      ],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { outcome: '"won"' },
    },
    {
      action: "finalize",
      label: "Mark as Lost",
      targetStatuses: [
        { key: "PendingLost", id: OpportunityStatus.PendingLost },
      ],
      requiresNote: true,
      requiresPermission: null,
      payloadHints: { outcome: '"lost"' },
    },
    {
      action: "resendQuote",
      label: "Revise & Re-send (back to Active)",
      targetStatuses: [{ key: "Active", id: OpportunityStatus.Active }],
      requiresNote: false,
      requiresPermission: null,
      payloadHints: { needsRevision: "true" },
    },
    {
      action: "sendBackForRevision",
      label: "Send Back for Revision",
      targetStatuses: [
        { key: "PendingRevision", id: OpportunityStatus.PendingRevision },
      ],
      requiresNote: true,
      requiresPermission: null,
    },
  ],

  [OpportunityStatus.Active]: [
    {
      action: "markReadyToSend",
      label: "Mark Ready to Send",
      targetStatuses: [
        { key: "ReadyToSend", id: OpportunityStatus.ReadyToSend },
      ],
      requiresNote: false,
      requiresPermission: null,
    },
    {
      action: "resendQuote",
      label: "Send Revised Quote",
      targetStatuses: [{ key: "QuoteSent", id: OpportunityStatus.QuoteSent }],
      requiresNote: false,
      requiresPermission: null,
      payloadHints: {
        quoteConfirmed: "boolean — mark confirmed simultaneously",
        won: "boolean — immediate win",
        lost: "boolean — immediate rejection",
      },
    },
    {
      action: "requestReview",
      label: "Send to Internal Review",
      targetStatuses: [
        { key: "InternalReview", id: OpportunityStatus.InternalReview },
      ],
      requiresNote: true,
      requiresPermission: null,
    },
    {
      action: "cancel",
      label: "Cancel Opportunity",
      targetStatuses: [{ key: "Canceled", id: OpportunityStatus.Canceled }],
      requiresNote: true,
      requiresPermission: WorkflowPermissions.CANCEL,
    },
  ],

  [OpportunityStatus.PendingWon]: [
    {
      action: "finalize",
      label: "Approve Won",
      targetStatuses: [{ key: "Won", id: OpportunityStatus.Won }],
      requiresNote: true,
      requiresPermission: WorkflowPermissions.FINALIZE,
      payloadHints: { outcome: '"won"' },
    },
  ],

  [OpportunityStatus.PendingLost]: [
    {
      action: "finalize",
      label: "Approve Lost",
      targetStatuses: [{ key: "Lost", id: OpportunityStatus.Lost }],
      requiresNote: true,
      requiresPermission: WorkflowPermissions.FINALIZE,
      payloadHints: { outcome: '"lost"' },
    },
    {
      action: "resurrect",
      label: "Resurrect (back to Active)",
      targetStatuses: [{ key: "Active", id: OpportunityStatus.Active }],
      requiresNote: true,
      requiresPermission: null,
    },
  ],

  [OpportunityStatus.Won]: [],
  [OpportunityStatus.Lost]: [],

  [OpportunityStatus.Canceled]: [
    {
      action: "reopen",
      label: "Re-open Opportunity",
      targetStatuses: [{ key: "Active", id: OpportunityStatus.Active }],
      requiresNote: true,
      requiresPermission: null,
    },
  ],
};

// ═══════════════════════════════════════════════════════════════════════════
// ROUTE
// ═══════════════════════════════════════════════════════════════════════════

/* GET /v1/sales/opportunities/opportunity/:identifier/workflow */
export default createRoute(
  "get",
  ["/opportunities/opportunity/:identifier/workflow"],
  async (c) => {
    try {
      const identifier = c.req.param("identifier");
      const user = c.get("user");

      const opportunity = await opportunities.fetchItem(identifier);

      const statusCwId = opportunity.statusCwId;
      const statusKey: OpportunityStatusKey | null =
        statusCwId != null ? (StatusIdToKey[statusCwId] ?? null) : null;

      const isOptimaStage = opportunity.stageName === "Optima";
      const isTerminal =
        statusCwId === OpportunityStatus.Won ||
        statusCwId === OpportunityStatus.Lost;

      // ── Resolve available actions (permission-aware) ──────────────────
      const rawActions =
        statusCwId != null ? (ACTION_MAP[statusCwId] ?? []) : [];

      const resolvedActions = await Promise.all(
        rawActions.map(async (a) => {
          const hasGate =
            !a.requiresPermission ||
            (await user.hasPermission(a.requiresPermission));
          return { ...a, permitted: hasGate };
        }),
      );

      // ── Cold check (only for QuoteSent / ConfirmedQuote) ──────────────
      let coldCheck: ColdCheckResult | null = null;
      if (
        statusCwId === OpportunityStatus.QuoteSent ||
        statusCwId === OpportunityStatus.ConfirmedQuote
      ) {
        // Fetch activities to determine latest activity date
        const activities = await opportunity.fetchActivities();
        const latestDate =
          activities.length > 0
            ? new Date(
                Math.max(
                  ...activities.map((a) => {
                    const json = a.toJson();
                    return new Date(
                      json.dateEnd ?? json.dateStart ?? 0,
                    ).getTime();
                  }),
                ),
              )
            : null;

        coldCheck = checkColdStatus({
          statusCwId,
          lastActivityDate: latestDate,
        });
      }

      const response = apiResponse.successful(
        "Workflow status fetched successfully.",
        {
          currentStatusId: statusCwId,
          currentStatus: statusKey,
          stageName: opportunity.stageName ?? null,
          isOptimaStage,
          isTerminal,
          availableActions: isOptimaStage ? resolvedActions : [],
          coldCheck,
        },
      );
      return c.json(response, response.status as ContentfulStatusCode);
    } catch (err) {
      console.error("[Workflow Status] Unhandled error:", err);
      throw err;
    }
  },
  authMiddleware({ permissions: ["sales.opportunity.fetch"] }),
);
