import { A, buildContract } from '@jig-software/trest-core';
import { objectId } from '@jig-software/zod-bson';
import { z } from 'zod';
import { Attendance, Leave, Staff } from '../schemas';
import { OK } from './common';

// Schema to be completed
export const StaffInit = Staff.omit({
  _id: true,
  createdAt: true,
  updatedAt: true,
});
export type StaffInit = z.infer<typeof StaffInit>;

export const StaffPatch = StaffInit;
export type StaffPatch = z.infer<typeof StaffPatch>;

export const StaffContext = Staff.extend({
  upComingLeaves: z.array(
    Leave.pick({
      type: true,
      status: true,
      workDay: true,
      applyRemarks: true,
      approveRemarks: true,
    }),
  ),
  lastAttendance: Attendance.pick({
    workDay: true,
    wfh: true,
  }).nullable(),
});

export type StaffContext = z.infer<typeof StaffContext>;

export const staffContract = buildContract((c) =>
  c
    .prefix('/staffs')
    .parse((p) => p.error.text(400))
    .endpoints({
      createStaff: (e) =>
        e
          .method('POST')
          .prepare((p) => p.body.json(StaffInit).annotate<[patch: A]>())
          .parse((p) => p.success.object(201, Staff)),
      getStaffs: (e) =>
        e.method('GET').parse((p) => p.success.object(200, z.array(Staff))),
      getStaff: (e) =>
        e
          .method('GET')
          .path('/:_id')
          .prepare((p) => p.param('_id', objectId()))
          .parse((p) => p.success.object(200, Staff).error.text(404)),

      updateStaff: (e) =>
        e
          .method('PATCH')
          .path('/:_id')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(StaffPatch)
              .annotate<[_id: A, patch: A]>(),
          )
          .parse((p) => p.success.object(200, Staff).error.text(404)),
      deleteStaff: (e) =>
        e
          .method('DELETE')
          .path('/:_id')
          .prepare((p) => p.param('_id', objectId()).annotate<[_id: A]>())
          .parse((p) => p.success.object(200, OK).error.text(404)),
      getStaffContext: (e) =>
        e
          .method('GET')
          .path('/:_id/context')
          .prepare((p) => p.param('_id', objectId()).annotate<[_id: A]>())
          .parse((p) => p.success.object(200, StaffContext).error.text(404)),
    }),
);
