import { SrService as CwSrService } from "../../generated/prisma/client";
import { ServiceTicket as ApiServiceTicket } from "../../../api/generated/prisma/client";
import { Translation, skipRow } from "./types";
import { TranslationContext } from "./context";

const toBillingMethod = (
  value: string | null | undefined
): "ACTUAL_RATES" | "FIXED_FEE" | "NOT_TO_EXCEED" | "OVERRIDE_RATE" => {
  if (!value) return "ACTUAL_RATES";

  const normalized = value.trim().toUpperCase();
  if (normalized === "A") return "ACTUAL_RATES";
  if (normalized === "F") return "FIXED_FEE";
  if (normalized === "N") return "NOT_TO_EXCEED";
  if (normalized === "O") return "OVERRIDE_RATE";

  // Keyword fallback for unexpected legacy values.
  if (normalized.includes("FIX")) return "FIXED_FEE";
  if (normalized.includes("EXCEED")) return "NOT_TO_EXCEED";
  if (normalized.includes("OVERRIDE")) return "OVERRIDE_RATE";

  return "ACTUAL_RATES";
};

const toBillingType = (value: string | undefined): "STANDARD" | "PROJECT" => {
  if (!value) return "STANDARD";
  const normalized = value.trim().toUpperCase();
  if (normalized.includes("PROJECT")) return "PROJECT";
  return "STANDARD";
};

const resolveUserId = (
  value: string | null | undefined,
  context: TranslationContext
): string | null => {
  if (!value) return null;

  const byIdentifier = context.usersByIdentifier.get(value);
  if (byIdentifier) return byIdentifier;

  const asRecId = Number.parseInt(value, 10);
  if (!Number.isNaN(asRecId)) {
    return context.usersByMemberRecId.get(asRecId) ?? null;
  }

  return null;
};

export const serviceTicketTranslation: Translation<
  CwSrService,
  ApiServiceTicket,
  TranslationContext
> = {
  values: [
    { from: "srServiceRecId", to: "id" },
    {
      from: "summary",
      to: "summary",
      process: (value) => {
        if (!value || value.trim() === "") {
          skipRow(
            "ServiceTicket summary is required and cannot be empty"
          );
        }
        return value;
      },
    },
    {
      from: "srLocationRecId",
      to: "locationId",
      process: (value) => {
        if (value == null) {
          skipRow("ServiceTicket locationId missing");
        }
        return value;
      },
    },
    {
      from: "srSourceRecId",
      to: "sourceId",
      process: (value) => {
        if (value == null) {
          skipRow("ServiceTicket sourceId missing");
        }
        return value;
      },
    },
    {
      from: "srUrgencyRecId",
      to: "priorityId",
    },
    {
      from: "srSeverityRecId",
      to: "severityId",
      process: (value) => {
        if (value == null) {
          skipRow("ServiceTicket severityId missing");
        }
        return value;
      },
    },
    {
      from: "srImpactRecId",
      to: "impactId",
      process: (value) => {
        if (value == null) {
          skipRow("ServiceTicket impactId missing");
        }
        return value;
      },
    },
    {
      from: "srBoardRecId",
      to: "serviceTicketBoardId",
      process: (value) => (value == null ? null : value),
    },
    { from: "companyRecId", to: "companyId" },
    { from: "contactRecId", to: "contactId" },
    { from: "companyAddressRecId", to: "companyAddressId" },
    { from: "billingCompanyRecId", to: "billingCompanyId" },
    { from: "billingAddressRecId", to: "billingAddressId" },
    {
      from: "ticketOwnerRecId",
      to: "ticketOwnerId",
      process: (value, context) => {
        if (!value) return null;
        return context.usersByMemberRecId.get(value) || null;
      },
    },
    {
      from: "enteredBy",
      to: "createdById",
      process: (value, context) => {
        return resolveUserId(value, context);
      },
    },
    {
      from: "updatedBy",
      to: "updatedById",
      process: (value, context) => {
        return resolveUserId(value, context);
      },
    },
    {
      from: "closedBy",
      to: "closedById",
      process: (value, context) => {
        return resolveUserId(value, context);
      },
    },
    {
      from: "dateEnteredUtc",
      to: "createdAt",
      process: (value) => value || null,
    },
    {
      from: "lastUpdatedUtc",
      to: "updatedAt",
      process: (value) => value || null,
    },
    { from: "dateClosedUtc", to: "closedAt" },
    {
      from: "isClosedFlag",
      to: "closedFlag",
    },
    {
      from: "billMethod",
      to: "billingMethod",
      process: (value, context) => {
        return toBillingMethod(value);
      },
    },
    {
      from: "srServiceRecId",
      to: "billingType",
      process: (value, context) => {
        return toBillingType(context.billingTypeByTicketId.get(value) ?? undefined);
      },
    },
    {
      from: "srServiceRecId",
      to: "billingInstructions",
      process: (value, context) => {
        return context.billingInstructionsByTicketId.get(value) ?? null;
      },
    },
    { from: "poNumber", to: "poNumber" },
    {
      from: "billingAmount",
      to: "billingAmount",
      process: (value) => (value == null ? 0 : Number(value)),
    },
    { from: "rejectedFlag", to: "rejectedFlag" },
    { from: "publishFlag", to: "publishFlag" },
    { from: "redFlag", to: "redFlag" },
  ],
};
