import { TimeEntry as CwTimeEntry } from "../../generated/prisma/client";
import { Translation, skipRow } from "./types";
import { TranslationContext } from "./context";

type ApiTimeEntryRecord = {
  id: number;
  uid: string;
  memberId: string | null;
  companyId: number;
  serviceTicketId: number | null;
  activityId: number | null;
  chargeCodeId: number | null;
  statusId: number | null;
  contactId: number | null;
  dateStart: Date | null;
  timeStart: Date | null;
  timeEnd: Date | null;
  notes: string | null;
  notesMd: string | null;
  internalNote: string | null;
  billableHours: number | null;
  actualHours: number | null;
  invoicedHours: number | null;
  deductedHours: number | null;
  hourlyRate: number | null;
  effectiveRate: number | null;
  issueFlag: boolean;
  mergedFlag: boolean;
  invoiceFlag: boolean;
  billableFlag: boolean;
  documentFlag: boolean;
  teProblemFlag: boolean;
  teResolutionFlag: boolean;
  teInternalAnalysisFlag: boolean;
  chargeToRecId: number | null;
  chargeToType: string | null;
  createdById: string | null;
  updatedById: string | null;
  originalAuthorId: string | null;
  createdAt: Date;
  updatedAt: Date;
};

export const timeEntryTranslation: Translation<
  CwTimeEntry,
  ApiTimeEntryRecord,
  TranslationContext
> = {
  values: [
    { from: "timeRecId", to: "id" },
    {
      from: "mobileGuid",
      to: "uid",
      process: (value: string) => value,
    },
    { from: "memberId", to: "memberId" },
    {
      from: "companyRecId",
      to: "companyId",
      process: (value: number, context: TranslationContext) => {
        if (!context.companyIds.has(value)) return skipRow(`company ${value} not found`);
        return value;
      },
    },
    {
      from: "srServiceRecId",
      to: "serviceTicketId",
      process: (value: number | null, context: TranslationContext) => {
        if (!value) return null;
        if (!context.serviceTicketIds.has(value)) return null;
        return value;
      },
    },
    {
      from: "soActivityRecId",
      to: "activityId",
      process: (value: number | null, context: TranslationContext) => {
        if (!value) return null;
        if (!context.activityIds.has(value)) return null;
        return value;
      },
    },
    {
      from: "teChargeCodeRecId",
      to: "chargeCodeId",
      process: (value: number | null, context: TranslationContext) => {
        if (!value) return null;
        if (!context.timeEntryChargeCodeIds.has(value)) return null;
        return value;
      },
    },
    {
      from: "teStatusId",
      to: "statusId",
      process: (value: number, context: TranslationContext) => {
        return context.timeEntryStatusIdByTeStatusId.get(value) ?? null;
      },
    },
    {
      from: "contactRecId",
      to: "contactId",
      process: (value: number | null, context: TranslationContext) => {
        if (!value) return null;
        if (!context.contactIds.has(value)) return null;
        return value;
      },
    },
    { from: "dateStart", to: "dateStart" },
    { from: "timeStart", to: "timeStart" },
    { from: "timeEnd", to: "timeEnd" },
    {
      from: "notes",
      to: "notes",
      process: (value: string | null) => value ?? null,
    },
    {
      from: "notesMarkdown",
      to: "notesMd",
      process: (value: string | null) => value ?? null,
    },
    { from: "internalNote", to: "internalNote" },
    {
      from: "hoursBill",
      to: "billableHours",
      process: (value) => (value != null ? Number(value) : null),
    },
    {
      from: "hoursActual",
      to: "actualHours",
      process: (value) => (value != null ? Number(value) : null),
    },
    {
      from: "hoursInvoiced",
      to: "invoicedHours",
      process: (value) => (value != null ? Number(value) : null),
    },
    {
      from: "hoursDeduct",
      to: "deductedHours",
      process: (value) => (value != null ? Number(value) : null),
    },
    {
      from: "hourlyRate",
      to: "hourlyRate",
      process: (value) => (value != null ? Number(value) : null),
    },
    {
      from: "effectiveRate",
      to: "effectiveRate",
      process: (value) => (value != null ? Number(value) : null),
    },
    {
      from: "issueFlag",
      to: "issueFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "mergedFlag",
      to: "mergedFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "invoiceFlag",
      to: "invoiceFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "billableFlag",
      to: "billableFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "documentFlag",
      to: "documentFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "teProblemFlag",
      to: "teProblemFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "teResolutionFlag",
      to: "teResolutionFlag",
      process: (value) => Boolean(value),
    },
    {
      from: "teInternalAnalysisFlag",
      to: "teInternalAnalysisFlag",
      process: (value) => Boolean(value),
    },
    { from: "chargeToRecId", to: "chargeToRecId" },
    { from: "chargeToType", to: "chargeToType" },
    { from: "enteredBy", to: "createdById" },
    { from: "updatedBy", to: "updatedById" },
    { from: "originalAuthor", to: "originalAuthorId" },
    {
      from: "dateEnteredUtc",
      to: "createdAt",
      process: (value) => (value as Date | null) ?? new Date(0),
    },
    {
      from: "lastUpdateUtc",
      to: "updatedAt",
      process: (value) => (value as Date | null) ?? new Date(0),
    },
  ],
};
