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

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

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

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

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

export const leaveCreditApplicationContract = buildContract((c) =>
  c
    .prefix('/leave-credit-applications')
    .parse((p) => p.error.text(400))
    .endpoints({
      createLeaveCreditApplication: (e) =>
        e
          .method('POST')
          .prepare((p) =>
            p.body.json(LeaveCreditApplicationInit).annotate<[init: A]>(),
          )
          .parse((p) => p.success.object(201, LeaveCreditApplication)),
      getLeaveCreditApplications: (e) =>
        e
          .method('GET')
          .parse((p) => p.success.object(200, z.array(LeaveCreditApplication))),
      approveLeaveCreditApplication: (e) =>
        e
          .method('POST')
          .path('/:_id/approval')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(LeaveCreditApplicationApprovalInit)
              .annotate<[_id: A, init: A]>(),
          )
          .parse((p) => p.success.object(200, LeaveCreditApplication)),
      rejectLeaveCreditApplication: (e) =>
        e
          .method('POST')
          .path('/:_id/rejection')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(LeaveCreditApplicationRejectionInit)
              .annotate<[_id: A, init: A]>(),
          )
          .parse((p) => p.success.object(200, LeaveCreditApplication)),
      cancelLeaveApplication: (e) =>
        e
          .method('POST')
          .path('/:_id/cancellation')
          .prepare((p) =>
            p
              .param('_id', objectId())
              .body.json(LeaveCreditApplicationCancellationInit)
              .annotate<[_id: A, init: A]>(),
          )
          .parse((p) => p.success.object(200, LeaveCreditApplication)),
    }),
);
