import { baseAPI } from "@/lib/api";
import type { UploadedFileMetadata } from "@/lib/document-file";
import type {
  ApiMinistryOpenIssue,
  ApiMinistryProgressReportAssignment,
  ApiProgressReportRgcDecision,
  ApiAssignmentProgressReportDeadline,
  ApiAssignmentProgressReportMeeting,
  ProgressReportDeadlineSlot,
  ProgressReportMeetingSlot,
  ProgressReportSemester,
} from "@/features/ministry/progress-report/service/progress-report-service";

import type { ProgressReportRow } from "../progress-report-data";

export type PswgAssignmentStatus =
  | "SHARED_WITH_PSWG"
  | "PSWG_REVIEWED"
  | "SUBMITTED"
  | "CDC_UNDER_REVIEW"
  | "COMPLETED";

export type ApiPswgRgcDecision = ApiProgressReportRgcDecision;

type PswgProgressReport = ApiMinistryProgressReportAssignment["progressReport"] & {
  draftSemesterReport: UploadedFileMetadata | null;
  finalSemesterReport: UploadedFileMetadata | null;
  meetings: ApiAssignmentProgressReportMeeting[];
};

export type ApiPswgProgressReportAssignment = Omit<
  ApiMinistryProgressReportAssignment,
  "openIssues" | "progressReport" | "status"
> & {
  status: PswgAssignmentStatus;
  progressReport: PswgProgressReport;
  openIssues?: ApiMinistryOpenIssue[];
  rgcDecisions?: ApiPswgRgcDecision[];
};

type PswgProgressReportListResponse = {
  data: ApiPswgProgressReportAssignment[];
  meta: { page: number; limit: number; total: number; totalPages: number };
};

export type ApiPswgProgressReportDetail = ApiPswgProgressReportAssignment & {
  openIssues: ApiMinistryOpenIssue[];
  rgcDecisions: ApiPswgRgcDecision[];
};

type PswgProgressReportDetailResponse = {
  data: ApiPswgProgressReportDetail;
};

const assignmentStatusLabels: Record<PswgAssignmentStatus, string> = {
  SHARED_WITH_PSWG: "Shared",
  PSWG_REVIEWED: "PSWG Reviewed",
  SUBMITTED: "Submitted",
  CDC_UNDER_REVIEW: "Under Review",
  COMPLETED: "Completed",
};

// The slot decides the meaning, never the position in the array.
function getMeetingDate(
  meetings: ApiAssignmentProgressReportMeeting[],
  slot: ProgressReportMeetingSlot,
) {
  return meetings.find((meeting) => meeting.slot === slot)?.meetingDate || "-";
}

function getDeadlineDate(
  deadlines: ApiAssignmentProgressReportDeadline[],
  slot: ProgressReportDeadlineSlot,
) {
  return deadlines.find((deadline) => deadline.slot === slot)?.deadline || "-";
}

export function mapPswgAssignmentToRow(
  assignment: ApiPswgProgressReportAssignment,
): ProgressReportRow {
  const report = assignment.progressReport;

  return {
    id: assignment.id,
    title: report.title,
    year: String(report.year),
    semester: report.semester as ProgressReportSemester,
    deadline: getDeadlineDate(report.deadlines, "FIRST"),
    firstMeeting: getMeetingDate(report.meetings, "FIRST"),
    secondDeadline: getDeadlineDate(report.deadlines, "SECOND"),
    secondMeeting: getMeetingDate(report.meetings, "SECOND"),
    thirdDeadline: getDeadlineDate(report.deadlines, "FINAL"),
    draftSemester: report.draftSemesterReport,
    reportDoc: report.requestDocument,
    status: assignmentStatusLabels[assignment.status],
  };
}

export async function getPswgProgressReports(): Promise<ProgressReportRow[]> {
  const response = (await baseAPI(
    "/progress-reports?page=1&limit=100",
  )) as PswgProgressReportListResponse;

  return response.data.map(mapPswgAssignmentToRow);
}

export async function getPswgProgressReport(
  assignmentId: number,
): Promise<PswgProgressReportDetailResponse["data"]> {
  const response = (await baseAPI(
    `/progress-reports/assignments/${assignmentId}`,
  )) as PswgProgressReportDetailResponse;

  return response.data;
}

export async function reviewPswgProgressReport(
  assignmentId: number,
): Promise<ApiPswgProgressReportDetail> {
  const response = (await baseAPI(
    `/progress-reports/assignments/${assignmentId}/review`,
    { method: "POST" },
  )) as PswgProgressReportDetailResponse;

  return response.data;
}

export function getPswgAssignmentStatusLabel(status: PswgAssignmentStatus) {
  return assignmentStatusLabels[status];
}
