import { A, buildContract } from '@jig-software/trest-core';
import { objectId } from '@jig-software/zod-bson';
import { z } from 'zod';
import { LeaveApplication } from '../schemas';

export const LeaveApplicationInit = LeaveApplication.pick({
  applyRemarks: true,
  leaves: true,
  appliedBy: true, // To be excluded, once auth ready.
});
export type LeaveApplicationInit = z.infer<typeof LeaveApplicationInit>;

export const LeaveApplicationApprovalInit = LeaveApplication.pick({
  approvedBy: true,
  approveRemarks: true,
});
export type LeaveApplicationApprovalInit = z.infer<
  typeof LeaveApplicationApprovalInit
>;

export const LeaveApplicationRejectionInit = LeaveApplication.pick({
  rejectedBy: true,
  rejectRemarks: true,
});
export type LeaveApplicationRejectionInit = z.infer<
  typeof LeaveApplicationRejectionInit
>;

export const LeaveApplicationCancellationInit = LeaveApplication.pick({
  canceledBy: true,
  cancelRemarks: true,
});
export type LeaveApplicationCancellationInit = z.infer<
  typeof LeaveApplicationCancellationInit
>;

export const leaveApplicationContract = buildContract((c) =>
  c
    .prefix('/leave-applications')
    .parse((p) => p.error.text(400))
    .endpoints({
      createLeaveApplication: (e) =>
        e
          .method('POST')
          .prepare((p) =>
            p.body.json(LeaveApplicationInit).annotate<[init: A]>(),
          )
          .parse((p) => p.success.object(201, LeaveApplication)),
      getLeaveApplications: (e) =>
        e
          .method('GET')
          .parse((p) => p.success.object(200, z.array(LeaveApplication))),
      getLeaveApplication: (e) =>
        e
          .method('GET')
          .path('/:_id')
          .prepare((p) => p.param('_id', objectId()))
          .parse((p) =>
            p.success.object(200, LeaveApplication).error.text(404),
          ),
      approveLeaveApplication: (e) =>
        e
          .method('POST')
          .path('/:_id/approval')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(LeaveApplicationApprovalInit)
              .annotate<[_id: A, init: A]>(),
          )
          .parse((p) => p.success.object(200, LeaveApplication)),
      rejectLeaveApplication: (e) =>
        e
          .method('POST')
          .path('/:_id/rejection')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(LeaveApplicationRejectionInit)
              .annotate<[_id: A, init: A]>(),
          )
          .parse((p) => p.success.object(200, LeaveApplication)),
      cancelLeaveApplication: (e) =>
        e
          .method('POST')
          .path('/:_id/cancellation')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(LeaveApplicationCancellationInit)
              .annotate<[_id: A, init: A]>(),
          )
          .parse((p) => p.success.object(200, LeaveApplication)),
    }),
);
