import type { MeetingCalendarApiMeeting } from "@/features/ministry/meeting-calendar/meeting-calendar-data";
import { EMPTY_MEETING_SUMMARY_PARTICIPANTS } from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-data";
import type {
  ViewMeetingSummaryDetail,
  ViewMeetingSummaryIssueRow,
} from "@/features/ministry/meeting-summary/components/view-meeting-summary/view-meeting-summary-data";
import { getDisplayFileName } from "@/lib/document-file";
import { resolveAgencyLogoForDisplay } from "@/features/ministry/meeting-summary/components/create-meeting-summary/meeting-summary-issue-agencies";

type ApiGovernmentAgency = {
  agencyOrder?: number | null;
  name?: string | null;
  logo?: string | null;
  stakeholder?: { name?: string | null; logo?: string | null } | null;
};

type ApiIssue = {
  id?: number | string;
  title?: string | null;
  issue?: string | null;
  description?: string | null;
  recommendation?: string | null;
  status?: string | null;
  primaryAgency?: string | null;
  primaryAgencyLogo?: string | null;
  secondAgency?: string | null;
  secondAgencyLogo?: string | null;
  thirdAgency?: string | null;
  thirdAgencyLogo?: string | null;
  fourthAgency?: string | null;
  fourthAgencyLogo?: string | null;
  fifthAgency?: string | null;
  fifthAgencyLogo?: string | null;
  category?: { name?: string | null } | string | null;
  issueStatus?: { name?: string | null } | null;
  governmentAgencies?: ApiGovernmentAgency[] | null;
};

function getApiOrigin() {
  const raw =
    process.env.NEXT_PUBLIC_API_URL ??
    process.env.NEXT_PUBLIC_API_BASE_URL ??
    "http://localhost:3001/api/v1";

  return raw.replace(/\/api\/v\d+\/?$/, "").replace(/\/+$/, "");
}

function getMediaUrl(path?: string | null) {
  if (!path) return "";
  if (/^https?:\/\//i.test(path)) return path;
  return `${getApiOrigin()}${path.startsWith("/") ? path : `/${path}`}`;
}

function stripHtmlText(value?: string | null) {
  if (!value) return "-";

  return (
    value
      .replace(/<[^>]*>/g, " ")
      .replace(/&amp;/g, "&")
      .replace(/&nbsp;/g, " ")
      .replace(/&quot;/g, '"')
      .replace(/&#39;/g, "'")
      .replace(/\s+/g, " ")
      .trim() || "-"
  );
}

function formatDetailDate(value?: string | null) {
  if (!value) return "-";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "-";

  return new Intl.DateTimeFormat("en-US", {
    month: "long",
    day: "numeric",
    year: "numeric",
    timeZone: "UTC",
  }).format(date);
}

function formatDetailTime(start?: string | null, end?: string | null) {
  const formatTime = (value?: string | null) => {
    if (!value) return "";
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) return "";

    return new Intl.DateTimeFormat("en-US", {
      hour: "numeric",
      minute: "2-digit",
      hour12: true,
      timeZone: "UTC",
    }).format(date);
  };

  const startLabel = formatTime(start);
  const endLabel = formatTime(end);

  if (startLabel && endLabel) return `${startLabel} - ${endLabel}`;
  return startLabel || endLabel || "-";
}

function getFileName(value?: string | null) {
  return getDisplayFileName(value);
}

function firstAgencyName(agencies?: ApiGovernmentAgency[] | null) {
  const firstAgency = agencies?.[0];
  return firstAgency?.stakeholder?.name || firstAgency?.name || "-";
}

function firstAgencyLogo(agencies?: ApiGovernmentAgency[] | null) {
  const firstAgency = agencies?.[0];
  return getMediaUrl(firstAgency?.stakeholder?.logo || firstAgency?.logo || "");
}

function getAgencyName(issue: ApiIssue, order: 1 | 2 | 3 | 4 | 5): string {
  const directKeys = [
    "primaryAgency",
    "secondAgency",
    "thirdAgency",
    "fourthAgency",
    "fifthAgency",
  ] as const;
  const direct = issue[directKeys[order - 1]];
  if (direct && direct !== "Not Uploaded") return direct;

  const agency = issue.governmentAgencies?.find(
    (item) => item.agencyOrder === order,
  );
  return agency?.stakeholder?.name || agency?.name || "Not Uploaded";
}

function getAgencyLogo(issue: ApiIssue, order: 1 | 2 | 3 | 4 | 5): string | null {
  const agencyName = getAgencyName(issue, order);
  const directLogoKeys = [
    "primaryAgencyLogo",
    "secondAgencyLogo",
    "thirdAgencyLogo",
    "fourthAgencyLogo",
    "fifthAgencyLogo",
  ] as const;
  const directLogo = issue[directLogoKeys[order - 1]];
  const fromDirect = directLogo ? getMediaUrl(directLogo) : null;

  const agency = issue.governmentAgencies?.find(
    (item) => item.agencyOrder === order,
  );
  const logo = agency?.stakeholder?.logo || agency?.logo || "";
  const fromRelation = getMediaUrl(logo);

  return resolveAgencyLogoForDisplay(
    agencyName,
    fromDirect ?? fromRelation,
  );
}

function mapIssue(
  issue: ApiIssue,
  wgName: string,
  index: number,
): ViewMeetingSummaryIssueRow {
  const primaryAgency = getAgencyName(issue, 1);
  const primaryAgencyLogo = getAgencyLogo(issue, 1);

  return {
    id: typeof issue.id === "number" ? issue.id : index + 1,
    wgName,
    issue: stripHtmlText(issue.issue || issue.title),
    category:
      (typeof issue.category === "string"
        ? issue.category
        : issue.category?.name) || "-",
    issueDescription: stripHtmlText(issue.description),
    recommendation: stripHtmlText(issue.recommendation),
    rgcDecision: "Not Uploaded",
    nextStep: "Not Uploaded",
    remark: "Not Uploaded",
    issueReference: "Not Uploaded",
    status: "New Submitted",
    primaryAgency,
    primaryAgencyLogo,
    secondAgency: getAgencyName(issue, 2),
    secondAgencyLogo: getAgencyLogo(issue, 2),
    thirdAgency: getAgencyName(issue, 3),
    thirdAgencyLogo: getAgencyLogo(issue, 3),
    fourthAgency: getAgencyName(issue, 4),
    fourthAgencyLogo: getAgencyLogo(issue, 4),
    fifthAgency: getAgencyName(issue, 5),
    fifthAgencyLogo: getAgencyLogo(issue, 5),
    issueEscalation: "Not Uploaded",
  };
}

export function mapMeetingToSummaryDetail(
  meeting: MeetingCalendarApiMeeting,
): ViewMeetingSummaryDetail {
  const request = meeting.meetingRequest;
  const agencies = (request?.governmentAgencies ?? []) as ApiGovernmentAgency[];
  const issues = (request?.issues ?? []) as ApiIssue[];
  const wgName =
    meeting.workingGroupName?.trim() || request?.privateSectorWG?.trim() || "-";
  const meetingRequestDocument = getFileName(request?.meetingRequestLetter);
  const meetingDocument = getFileName(
    meeting.documentReference || request?.meetingRequestLetter,
  );

  return {
    id: meeting.id,
    share: false,
    privateSectorWg: wgName,
    meetingRequestDocument,
    meetingRequestDocumentSize: "—",
    wgMeeting: wgName,
    meetingDocument,
    meetingDocumentSize: "—",
    governmentAgency: firstAgencyName(agencies),
    governmentAgencyLogo: firstAgencyLogo(agencies) || null,
    sentBy: request?.submittedBy || request?.requestedBy || "-",
    time: formatDetailTime(meeting.startTime, meeting.endTime),
    date: formatDetailDate(meeting.meetingDate),
    location: meeting.location?.trim() || "-",
    participants: EMPTY_MEETING_SUMMARY_PARTICIPANTS,
    summaryReference: {
      name: "",
      size: "",
      uploadStatus: "Uploading",
      url: null,
    },
    issues: issues.map((issue, index) => mapIssue(issue, wgName, index)),
  };
}
