import {
  BillingType,
  Employee,
  Project,
  Task,
  Bug,
  Timesheet,
  TimesheetApproval,
  TimesheetCategory,
} from '@prisma/client';
import { billingToDb } from './task';

const categoryFromDb: Record<TimesheetCategory, string> = {
  Analysis: 'Analysis',
  Development: 'Development',
  UnitTesting: 'Unit Testing',
  CodeReview: 'Code Review',
  QA: 'QA',
  BugFixing: 'Bug Fixing',
  Other: 'Other',
};

const categoryToDbMap: Record<string, TimesheetCategory> = {
  Analysis: TimesheetCategory.Analysis,
  Development: TimesheetCategory.Development,
  'Unit Testing': TimesheetCategory.UnitTesting,
  UnitTesting: TimesheetCategory.UnitTesting,
  'Code Review': TimesheetCategory.CodeReview,
  CodeReview: TimesheetCategory.CodeReview,
  QA: TimesheetCategory.QA,
  'Bug Fixing': TimesheetCategory.BugFixing,
  BugFixing: TimesheetCategory.BugFixing,
  Other: TimesheetCategory.Other,
};

const billingFromDb: Record<BillingType, string> = {
  Billable: 'Billable',
  NonBillable: 'Non-billable',
};

type EmpPick = Pick<Employee, 'id' | 'name' | 'code' | 'avatarColor'>;

type Row = Timesheet & {
  employee?: EmpPick | null;
  project?: Pick<Project, 'id' | 'code' | 'name'> | null;
  task?: Pick<Task, 'id' | 'code' | 'title' | 'billingType'> | null;
  bug?: Pick<Bug, 'id' | 'code' | 'title'> | null;
};

export function categoryToDb(label: string): TimesheetCategory {
  const v = categoryToDbMap[label];
  if (!v) throw new Error('Invalid category: ' + label);
  return v;
}

export function categoryFromTimesheetDb(c: TimesheetCategory): string {
  return categoryFromDb[c] || c;
}

export function serializeTimesheet(t: Row) {
  return {
    id: t.id,
    employeeId: t.employeeId,
    employee: t.employee
      ? {
          id: t.employee.id,
          name: t.employee.name,
          code: t.employee.code,
          avatarColor: t.employee.avatarColor,
        }
      : null,
    projectId: t.projectId,
    project: t.project
      ? { id: t.project.id, code: t.project.code, name: t.project.name }
      : null,
    taskId: t.taskId,
    task: t.task
      ? {
          id: t.task.id,
          code: t.task.code,
          title: t.task.title,
          billingType: billingFromDb[t.task.billingType],
        }
      : null,
    bugId: t.bugId,
    bug: t.bug
      ? { id: t.bug.id, code: t.bug.code, title: t.bug.title }
      : null,
    workDate: t.workDate.toISOString().slice(0, 10),
    hours: Number(t.hours),
    category: categoryFromTimesheetDb(t.category),
    description: t.description,
    billingType: billingFromDb[t.billingType],
    approvalStatus: t.approvalStatus === TimesheetApproval.Approved ? 'Approved' : 'Pending',
    fromTimer: t.fromTimer,
    autoClosed: t.autoClosed,
    createdAt: t.createdAt.toISOString(),
    updatedAt: t.updatedAt.toISOString(),
  };
}

export { billingToDb, TimesheetCategory, TimesheetApproval };
