import { defaultGqlPermission, defaultPermission } from "@tailor-platform/erp-kit/core";
import { db, type TailorAnyDBType } from "@tailor-platform/sdk";
import { approvalRequest } from "./approvalRequest";
import { approvalStep } from "./approvalStep";

const APPROVAL_DECISION_TYPES = [
  "APPROVE",
  "REJECT",
  "SEND_BACK",
  "DELEGATE",
  "WITHDRAW",
  "CANCEL",
  "RESUBMIT",
] as const;

export interface CreateApprovalDecisionTypeParams {
  userType?: TailorAnyDBType;
}

export function createApprovalDecisionType(params: CreateApprovalDecisionTypeParams) {
  const decidedByUserId = db
    .uuid()
    .description("Foreign key to User who recorded the decision (set from ctx.actorId)");
  const delegatedToUserId = db
    .uuid({ optional: true })
    .description("Delegate user; non-null on DELEGATE rows only");
  return db
    .type("ApprovalDecision", {
      approvalRequestId: db
        .uuid()
        .relation({
          type: "n-1",
          toward: { type: approvalRequest },
          backward: "decisions",
        })
        .description("Foreign key to parent ApprovalRequest (always required)"),
      approvalStepId: db
        .uuid({ optional: true })
        .relation({
          type: "n-1",
          toward: { type: approvalStep },
          backward: "decisions",
        })
        .description(
          "Foreign key to ApprovalStep; set on APPROVE/REJECT/SEND_BACK/DELEGATE, null on WITHDRAW/CANCEL/RESUBMIT",
        ),
      decision: db
        .enum(APPROVAL_DECISION_TYPES)
        .description(
          "Decision type: APPROVE, REJECT, SEND_BACK, DELEGATE, WITHDRAW, CANCEL, or RESUBMIT",
        ),
      decidedByUserId: params.userType
        ? decidedByUserId.relation({
            type: "n-1",
            toward: { type: params.userType },
            backward: "approvalDecisionsDecided",
          })
        : decidedByUserId,
      delegatedToUserId: params.userType
        ? delegatedToUserId.relation({
            type: "n-1",
            toward: { type: params.userType, as: "delegatedToUser" },
            backward: "approvalDecisionsDelegatedTo",
          })
        : delegatedToUserId,
      comment: db
        .string({ optional: true })
        .description(
          "Optional free-text on APPROVE/DELEGATE/WITHDRAW/RESUBMIT; required on REJECT/SEND_BACK/CANCEL as reason",
        ),
      decidedAt: db
        .datetime()
        .description("Decision timestamp; chronological key for getApprovalDecisionHistory"),
      ...db.fields.timestamps(),
    })
    .permission(defaultPermission)
    .gqlPermission(defaultGqlPermission);
}

export const approvalDecision = createApprovalDecisionType({});
