import type { InitiativeDraft } from '@/components/applicant/initiative-draft/types';
import type { ApplicationFormState, InitiativeFormState } from '@/components/applicant/initiativeFormTypes';
import type { ContributionDraftShape } from '@/components/applicant/initiative-draft/contributionDraftTypes';
import {
  authorByIdMap,
  resolveDonViCongTacDisplay,
  resolveWorkUnitForContributionRow,
} from '@/components/applicant/initiative-draft/mergeContributionWorkUnits';
import emptyTemplate from './bieu_mau_sang_kien_template.json';
import { applyBanCamKetToOfficialDoc } from '@/components/applicant/initiative-draft/mapBanCamKetToOfficialBieuMau';
import { applyReferenceMaterialHonestyToOfficialDoc } from '@/components/applicant/initiative-draft/mapReferenceMaterialHonestyToOfficialBieuMau';
import { applyResearchDomesticHonestyToOfficialDoc } from '@/components/applicant/initiative-draft/mapResearchDomesticHonestyToOfficialBieuMau';
import {
  displayDobStoredAsDdMm,
  parseContributionSubmissionDateInput,
} from '@/lib/vnDateFormat';

/**
 * Canonical shape of `bieu_mau_sang_kien_template.json` (public + bundled copy).
 * Used for DOCX/Jinja pipelines (be01) and API persistence aligned with official form labels.
 */
export type OfficialBieuMauDocument = typeof emptyTemplate;

function cloneEmpty(): OfficialBieuMauDocument {
  return JSON.parse(JSON.stringify(emptyTemplate)) as OfficialBieuMauDocument;
}

function padTrialRows(
  rows: Array<{ TT: string; 'Tên tổ chức/cá nhân': string; 'Địa chỉ': string; 'Lĩnh vực áp dụng sáng kiến': string }>,
  source: { name: string; address: string; field: string }[],
): void {
  rows.length = 0;
  source.forEach((u, i) => {
    rows.push({
      TT: String(i + 1),
      'Tên tổ chức/cá nhân': u.name,
      'Địa chỉ': u.address,
      'Lĩnh vực áp dụng sáng kiến': u.field,
    });
  });
  if (rows.length === 0) {
    rows.push({
      TT: '',
      'Tên tổ chức/cá nhân': '',
      'Địa chỉ': '',
      'Lĩnh vực áp dụng sáng kiến': '',
    });
  }
}

function classificationToCheckboxes(
  c: ApplicationFormState['initiativeClassification'],
): Record<string, boolean> {
  return {
    'Giải pháp kỹ thuật, quản lý, tác nghiệp, ứng dụng tiến bộ kỹ thuật áp dụng cho ĐHYD TP.HCM':
      c === 'technical',
    'Sáng kiến – cải tiến kỹ thuật từ các nghiên cứu khoa học có kết quả được đăng tải trên các tạp chí, hội nghị trong nước và quốc tế':
      c === 'research',
    'Sáng kiến – cải tiến kỹ thuật từ sách, giáo trình, tài liệu tham khảo': c === 'textbook',
  };
}

/**
 * Maps applicant draft + contribution into the nested Vietnamese-key JSON used by
 * `public/assets/bieu_mau_sang_kien_template.json` and `be0/src/be01/data_blank.json` (same semantics; be01 uses snake_case keys).
 *
 * **ReviewPanel** sources: `useDraft()` → `draft.application`, `draft.report`, and `contributionDraft`
 * (same objects passed to {@link buildTemplateDataFromDraft}).
 *
 * **Gaps (left empty / false):** Mẫu 04 (council evaluation). **Bản cam kết** is filled from
 * `application.banCamKet` via {@link applyBanCamKetToOfficialDoc}.
 *
 * **Effectiveness:** the form stores 7 text fields; the official template lists 10 bullets — see `mapEffectivenessToMau01`.
 */
export function buildOfficialBieuMauFromDraft(
  draft: InitiativeDraft,
  contribution?: Record<string, unknown> | null,
): OfficialBieuMauDocument {
  const a = draft.application as unknown as ApplicationFormState;
  const r = draft.report as unknown as InitiativeFormState;
  const c = (contribution ?? {}) as ContributionDraftShape;

  const doc = cloneEmpty();

  const initiativeTitle = (a.initiativeName || r.initiativeName || '').trim();
  const authorsLine = a.authors.map((x) => x.name).filter(Boolean).join('; ');
  const donViCongTacDisplay = resolveDonViCongTacDisplay(a, c);

  // —— TRANG BÌA ——
  const bia = doc['TRANG BÌA'];
  bia['Tên sáng kiến (Tiếng Việt)'] = initiativeTitle;
  bia['Tác giả/nhóm tác giả sáng kiến'] = authorsLine;
  bia['Đơn vị công tác'] = donViCongTacDisplay;
  bia['Thông tin liên hệ (Điện thoại, Email)'] = [r.representativePhone, r.representativeEmail]
    .filter(Boolean)
    .join(' · ');
  bia['Năm'] = String(a.submissionYear || new Date().getFullYear());

  // —— MẪU 01 ——
  const m01 = doc['MẪU SỐ 01 - BÁO CÁO MÔ TẢ SÁNG KIẾN'];
  m01['1. Mở đầu'] = r.introduction;
  m01['2. Tên sáng kiến (tên quy trình, giải pháp, phương pháp)'] = r.initiativeName || initiativeTitle;
  m01['3. Lĩnh vực áp dụng của sáng kiến'] = r.applicationField || a.applicationField;

  const m4 = m01['4. Mô tả sáng kiến'];
  m4['4.1 Tình trạng giải pháp đã biết hoặc hiện trạng công tác khi chưa có sáng kiến'] =
    r.currentStatus;

  const inner = m4['4.2 Nội dung giải pháp đề nghị công nhận là sáng kiến'];
  inner['Mục đích của sáng kiến'] = r.purpose;

  const nd = inner['Về nội dung của sáng kiến'];
  nd['Các bước thực hiện giải pháp'] = r.implementationSteps;
  nd['Các điều kiện cần thiết để áp dụng giải pháp'] = r.conditions;
  nd['Lĩnh vực áp dụng'] = r.applicationField || a.applicationField;
  nd['Kết quả thu được'] = r.achievedResult;
  padTrialRows(nd['Danh sách đơn vị/cá nhân đã tham gia áp dụng thử hoặc lần đầu'], r.trialUnits);

  inner['Về tính mới của sáng kiến'] = r.novelty;
  mapEffectivenessToMau01(inner['Về tính hiệu quả'], r);

  m01['6. Những thông tin cần được bảo mật (nếu có)'] = r.confidentialInfo;

  const nk = m01['Ngày ký'];
  nk['Ngày'] = String(a.submissionDay);
  nk['Tháng'] = String(a.submissionMonth);
  nk['Năm'] = String(a.submissionYear);

  m01['Lãnh đạo đơn vị (Ký, ghi rõ họ tên)'] = '';
  m01['Tác giả sáng kiến (Ký, ghi rõ họ tên)'] = r.authorName || r.representativeAuthor || authorsLine;

  // —— MẪU 02 —— (Đơn — application tab)
  const m02 = doc['MẪU SỐ 02 - ĐƠN ĐỀ NGHỊ CÔNG NHẬN SÁNG KIẾN'];
  m02['Đơn vị'] = donViCongTacDisplay;
  m02['Danh sách tác giả'] = a.authors.map((x, i) => ({
    STT: String(i + 1),
    'Họ và tên': x.name,
    'Ngày tháng năm sinh': displayDobStoredAsDdMm(x.dob),
    'Nơi công tác': x.workplace,
    'Chức danh': x.title,
    'Trình độ chuyên môn': x.qualification,
    'Tỷ lệ (%) đóng góp vào việc tạo ra sáng kiến': String(x.contributionPercent),
  }));
  if (m02['Danh sách tác giả'].length === 0) {
    m02['Danh sách tác giả'].push({
      STT: '',
      'Họ và tên': '',
      'Ngày tháng năm sinh': '',
      'Nơi công tác': '',
      'Chức danh': '',
      'Trình độ chuyên môn': '',
      'Tỷ lệ (%) đóng góp vào việc tạo ra sáng kiến': '',
    });
  }

  m02['Tên sáng kiến đề nghị xét công nhận'] = a.initiativeName;
  m02['Chủ đầu tư tạo ra sáng kiến'] = a.investorName;
  m02['Lĩnh vực áp dụng sáng kiến'] = a.applicationField;
  m02['Ngày sáng kiến được áp dụng'] = a.firstApplyDate;
  m02['Nội dung của sáng kiến'] = a.contentSummary;

  Object.assign(m02['Phân loại sáng kiến (đánh dấu ☑)'], classificationToCheckboxes(a.initiativeClassification));

  m02['Những thông tin cần được bảo mật (nếu có)'] = a.confidentialInfo;
  m02['Các điều kiện cần thiết để áp dụng sáng kiến'] = a.conditions;
  m02['Đánh giá lợi ích theo ý kiến của tác giả'] = a.authorEvaluation;
  m02['Đánh giá lợi ích theo ý kiến của tổ chức, cá nhân đã tham gia áp dụng sáng kiến lần đầu'] =
    a.trialEvaluation;

  m02['Danh sách những người đã tham gia áp dụng thử hoặc áp dụng sáng kiến lần đầu'] =
    a.supportStaff.map((x, i) => ({
      'Số TT': String(i + 1),
      'Họ và tên': x.name,
      'Ngày tháng năm sinh': displayDobStoredAsDdMm(x.dob),
      'Nơi công tác': x.workplace,
      'Chức danh': x.title,
      'Trình độ chuyên môn': x.qualification,
      'Nội dung công việc hỗ trợ': x.supportContent,
    }));
  if (m02['Danh sách những người đã tham gia áp dụng thử hoặc áp dụng sáng kiến lần đầu'].length === 0) {
    m02['Danh sách những người đã tham gia áp dụng thử hoặc áp dụng sáng kiến lần đầu'].push({
      'Số TT': '',
      'Họ và tên': '',
      'Ngày tháng năm sinh': '',
      'Nơi công tác': '',
      'Chức danh': '',
      'Trình độ chuyên môn': '',
      'Nội dung công việc hỗ trợ': '',
    });
  }

  const m02nk = m02['Ngày ký'];
  m02nk['Ngày'] = String(a.submissionDay);
  m02nk['Tháng'] = String(a.submissionMonth);
  m02nk['Năm'] = String(a.submissionYear);
  m02['Xác nhận của lãnh đạo Đơn vị'] = '';
  m02['Tác giả sáng kiến (Ký, ghi rõ họ tên)'] = r.authorName || r.representativeAuthor || '';

  // —— MẪU 03 —— (contribution tab)
  const m03 = doc['MẪU SỐ 03 - BẢN XÁC NHẬN TỶ LỆ (%) ĐÓNG GÓP VÀO VIỆC TẠO RA SÁNG KIẾN'];
  const m03nk = m03['Ngày ký'];
  if (c.submissionDate) {
    const d = parseContributionSubmissionDateInput(c.submissionDate);
    if (d && !Number.isNaN(d.getTime())) {
      m03nk['Ngày'] = String(d.getDate());
      m03nk['Tháng'] = String(d.getMonth() + 1);
      m03nk['Năm'] = String(d.getFullYear());
    }
  }
  m03['1. Tên sáng kiến'] = c.initiativeName || initiativeTitle;
  m03['2. Tác giả chính/Đại diện nhóm tác giả sáng kiến'] = c.mainAuthor || r.representativeAuthor || '';
  /**
   * `position` is last-saved contribution JSON; `authors[0].workplace` is live Đơn « Nơi công tác »
   * (dropdown). Prefer the latter so preview matches the application tab without re-saving Xác nhận.
   */
  const contribPosition = (c.position != null && String(c.position).trim()) || '';
  const firstAuthorUnit = (a.authors[0]?.workplace != null && String(a.authors[0].workplace).trim()) || '';
  m03['Chức vụ, đơn vị công tác'] = firstAuthorUnit || contribPosition || donViCongTacDisplay || '';

  const tyLe = m03['Tỷ lệ đóng góp'];
  tyLe.length = 0;
  const parts = c.participants ?? [];
  const authorIds = authorByIdMap(a.authors);
  parts.forEach((p, i) => {
    tyLe.push({
      STT: String(i + 1),
      'Họ và tên': p.fullName,
      'Đơn vị công tác': resolveWorkUnitForContributionRow(authorIds, p),
      '% đóng góp': String(p.contributionPercent),
      'Chữ ký xác nhận': '',
    });
  });
  if (a.authors.length && tyLe.length === 0) {
    a.authors.forEach((x, i) => {
      tyLe.push({
        STT: String(i + 1),
        'Họ và tên': x.name,
        'Đơn vị công tác': x.workplace,
        '% đóng góp': String(x.contributionPercent),
        'Chữ ký xác nhận': '',
      });
    });
  }
  if (tyLe.length === 0) {
    tyLe.push({
      STT: '',
      'Họ và tên': '',
      'Đơn vị công tác': '',
      '% đóng góp': '',
      'Chữ ký xác nhận': '',
    });
  }

  const sum = parts.reduce((s, p) => s + (Number(p.contributionPercent) || 0), 0);
  m03['Tổng % đóng góp'] = sum > 0 ? String(sum) : '100';
  m03['Tác giả chính/Đại diện nhóm tác giả sáng kiến (chữ ký và ghi rõ họ tên)'] =
    c.mainAuthor || r.representativeAuthor || '';

  // Mẫu 04: hội đồng — giữ mặc định từ template
  applyBanCamKetToOfficialDoc(doc, a.banCamKet);
  applyReferenceMaterialHonestyToOfficialDoc(doc, a.referenceMaterialHonesty);
  applyResearchDomesticHonestyToOfficialDoc(doc, a.researchDomesticHonesty);

  return doc;
}

function mapEffectivenessToMau01(
  target: OfficialBieuMauDocument['MẪU SỐ 01 - BÁO CÁO MÔ TẢ SÁNG KIẾN']['4. Mô tả sáng kiến']['4.2 Nội dung giải pháp đề nghị công nhận là sáng kiến']['Về tính hiệu quả'],
  r: InitiativeFormState,
): void {
  const e = r.effectiveness;
  target['Tạo ra lợi ích kinh tế'] = e.economic;
  target['Đem lại hiệu quả trong giảng dạy'] = e.teaching;
  target['Tăng năng suất lao động'] = e.productivity;
  target['Nâng cao hiệu quả công việc'] = e.social;
  target['Nâng cao chất lượng công việc, dịch vụ'] = e.quality;
  target['Giảm chi phí'] = '';
  target['Cải thiện môi trường, điều kiện học tập, làm việc, sống'] = e.environment;
  target['Bảo vệ sức khỏe'] = '';
  target['Đảm bảo an toàn lao động, PCCC'] = e.safety;
  target['Nâng cao khả năng, trình độ, nhận thức, trách nhiệm'] = '';
}
