/**
 * Gating rules for per-tab honesty / signature checkboxes (applicant flow).
 * Evidence PDF = classification-specific minh chứng on Đơn (uploaded to MinIO via draft APIs when possible).
 */

import type { FileHandle, StoredApplicationForm } from '../initiative/types';
import type {
  ApplicationFormState,
  Author,
  InitiativeClassification,
  InitiativeFormState,
} from '../initiative/initiativeFormTypes';
import {
  ensureBanCamKet,
  ensureReferenceMaterialHonesty,
  ensureResearchDomesticHonesty,
  isBanCamKetComplete,
  isReferenceMaterialHonestyComplete,
  isResearchDomesticHonestyComplete,
} from '../initiative/initiativeFormTypes';
import { parseDdMmYyyy } from './vnDateFormat';

const FIRST_APPLY_DATE_MIN = new Date(2025, 3, 15);
const FIRST_APPLY_DATE_MAX = new Date(2026, 3, 15);

function push(cond: boolean, gaps: string[], msg: string) {
  if (!cond) gaps.push(msg);
}

/** Minh chứng PDF present locally or already stored (IndexedDB handle / MinIO metadata). */
export function applicantEvidencePdfPresent(file: File | FileHandle | null | undefined): boolean {
  if (!file) return false;
  if (file instanceof File) return file.size > 0;
  const h = file as FileHandle;
  if (String(h.serverStorageKey ?? '').trim().length > 0) return true;
  return Number(h.size) > 0;
}

function collectAuthorRowGaps(authors: Author[]): string[] {
  const gaps: string[] = [];
  if (!authors.length) {
    gaps.push('Đơn: thêm ít nhất một tác giả.');
    return gaps;
  }
  authors.forEach((a, i) => {
    const p = `Đơn — tác giả ${i + 1}`;
    push(Boolean(a.name?.trim()), gaps, `${p}: họ tên`);
    push(Boolean(a.dob?.trim()), gaps, `${p}: ngày sinh`);
    push(Boolean(a.workplace?.trim()), gaps, `${p}: nơi công tác`);
    push(Boolean(a.title?.trim()), gaps, `${p}: chức danh`);
    push(Boolean(a.qualification?.trim()), gaps, `${p}: trình độ`);
  });
  const sum = authors.reduce((s, a) => s + Number(a.contributionPercent || 0), 0);
  push(sum === 100, gaps, 'Đơn: tổng % đóng góp của các tác giả phải bằng 100%.');
  return gaps;
}

function collectClassificationEvidenceGaps(a: ApplicationFormState | StoredApplicationForm): string[] {
  const gaps: string[] = [];
  const c = a.initiativeClassification as InitiativeClassification;
  if (!c) return gaps;

  if (c === 'technical') {
    push(applicantEvidencePdfPresent(a.technicalEvidenceFile), gaps, 'Đơn (Nhóm 1): cần tệp PDF minh chứng kỹ thuật / văn bản đơn vị.');
    return gaps;
  }

  if (c === 'textbook') {
    push(Boolean(a.textbookEvidenceKind), gaps, 'Đơn (Nhóm 2.2): chọn loại minh chứng (xuất sắc / tài liệu tham khảo).');
    push(applicantEvidencePdfPresent(a.textbookEvidenceFile), gaps, 'Đơn (Nhóm 2.2): cần tệp PDF minh chứng (Quyết định xuất bản…).');
    if (a.textbookEvidenceKind === 'book') {
      push(isBanCamKetComplete(ensureBanCamKet(a.banCamKet)), gaps, 'Đơn (Nhóm 2.2 — sách/giáo trình): hoàn thành bản cam kết tác giả.');
    }
    if (a.textbookEvidenceKind === 'reference') {
      push(
        isReferenceMaterialHonestyComplete(ensureReferenceMaterialHonesty(a.referenceMaterialHonesty)),
        gaps,
        'Đơn (Nhóm 2.2 — tài liệu tham khảo): hoàn thành biểu xác minh trung thực.',
      );
    }
    return gaps;
  }

  if (c === 'research') {
    push(Boolean(a.researchEvidenceKind), gaps, 'Đơn (Nhóm 2.1): chọn loại minh chứng (tạp chí / poster…).');
    push(applicantEvidencePdfPresent(a.researchEvidenceFile), gaps, 'Đơn (Nhóm 2.1): cần tệp PDF minh chứng bài báo / poster.');
    if (a.researchEvidenceKind === 'international') {
      const banOk = isBanCamKetComplete(ensureBanCamKet(a.banCamKet));
      const legacy = Boolean(a.internationalJournalDeclaration?.trim());
      push(banOk || legacy, gaps, 'Đơn (Nhóm 2.1 — quốc tế): hoàn thành bản cam kết tác giả hoặc tuyên bố tạp chí.');
    }
    if (a.researchEvidenceKind === 'domestic') {
      const domesticDeclarationOk =
        isResearchDomesticHonestyComplete(ensureResearchDomesticHonesty(a.researchDomesticHonesty)) ||
        isBanCamKetComplete(ensureBanCamKet(a.banCamKet));
      push(
        domesticDeclarationOk,
        gaps,
        'Đơn (Nhóm 2.1 — trong nước): hoàn thành biểu xác nhận bài báo trong nước.',
      );
    }
  }

  return gaps;
}

/** Tab « Báo cáo » — ô cam kết cuối báo cáo. */
export function collectReportTabHonestyGaps(r: InitiativeFormState): string[] {
  const gaps: string[] = [];
  push(r.introduction.trim().length > 0, gaps, 'Báo cáo: Mở đầu (§1)');
  push(r.initiativeName.trim().length > 0, gaps, 'Báo cáo: Tên sáng kiến');
  push(r.representativeAuthor.trim().length > 0, gaps, 'Báo cáo: Tác giả đại diện');
  push(r.representativePhone.trim().length > 0, gaps, 'Báo cáo: Điện thoại');
  push(r.representativeEmail.trim().length > 0, gaps, 'Báo cáo: Email');
  push(r.applicationField.trim().length > 0, gaps, 'Báo cáo: Lĩnh vực áp dụng');
  push(r.currentStatus.trim().length > 0, gaps, 'Báo cáo: Hiện trạng / giải pháp đã biết (§4.1)');
  push(r.purpose.trim().length > 0, gaps, 'Báo cáo: Mục đích (§4.2)');
  push(r.implementationSteps.trim().length > 0, gaps, 'Báo cáo: Các bước thực hiện');
  push(r.firstAppliedUnit.trim().length > 0, gaps, 'Báo cáo: Đơn vị áp dụng lần đầu');
  push(r.achievedResult.trim().length > 0, gaps, 'Báo cáo: Kết quả thu được');
  push(r.conditions.trim().length > 0, gaps, 'Báo cáo: Điều kiện áp dụng');
  push(r.novelty.trim().length > 0, gaps, 'Báo cáo: Tính mới của sáng kiến');
  const eff = r.effectiveness;
  push(eff.economic.trim().length > 0, gaps, 'Báo cáo: Hiệu quả kinh tế');
  push(eff.teaching.trim().length > 0, gaps, 'Báo cáo: Hiệu quả công việc / giảng dạy');
  push(eff.safety.trim().length > 0, gaps, 'Báo cáo: Môi trường & an toàn');
  push(eff.social.trim().length > 0, gaps, 'Báo cáo: Nhận thức & xã hội');
  return gaps;
}

/** Tab « Đơn » — ô cam kết cuối đơn (kèm PDF minh chứng theo phân loại). */
export function collectApplicationTabHonestyGaps(a: ApplicationFormState | StoredApplicationForm): string[] {
  const gaps: string[] = [];
  const unitDisplay =
    a.unitName.trim().length > 0 ? true : Boolean(a.authors[0]?.workplace?.trim());
  push(unitDisplay, gaps, 'Đơn: Tên đơn vị');
  gaps.push(...collectAuthorRowGaps(a.authors));
  push(a.initiativeName.trim().length > 0, gaps, 'Đơn: Tên sáng kiến');
  push(a.investorName.trim().length > 0, gaps, 'Đơn: Chủ đầu tư');
  push(a.applicationField.trim().length > 0, gaps, 'Đơn: Lĩnh vực áp dụng');
  const fad = a.firstApplyDate?.trim() ?? '';
  const parsed = fad ? parseDdMmYyyy(fad) : null;
  push(Boolean(parsed), gaps, 'Đơn: Ngày áp dụng lần đầu (định dạng dd/mm/yyyy)');
  if (parsed && (parsed < FIRST_APPLY_DATE_MIN || parsed > FIRST_APPLY_DATE_MAX)) {
    gaps.push('Đơn: Ngày áp dụng lần đầu phải từ 15/04/2025 đến 15/04/2026.');
  }
  push(a.initiativeClassification != null, gaps, 'Đơn: Phân loại sáng kiến (Nhóm 1 / 2.1 / 2.2)');
  gaps.push(...collectClassificationEvidenceGaps(a));
  push(a.contentSummary.trim().length > 0, gaps, 'Đơn: Nội dung của sáng kiến (§4)');
  push(a.conditions.trim().length > 0, gaps, 'Đơn: Điều kiện áp dụng');
  push(a.authorEvaluation.trim().length > 0, gaps, 'Đơn: Đánh giá lợi ích (tác giả)');
  push(a.trialEvaluation.trim().length > 0, gaps, 'Đơn: Đánh giá (đơn vị áp dụng thử)');
  if (a.supportStaff.length > 0) {
    a.supportStaff.forEach((s, i) => {
      const p = `Đơn — người hỗ trợ ${i + 1}`;
      push(Boolean(s.name?.trim()), gaps, `${p}: họ tên`);
      push(Boolean(s.dob?.trim()), gaps, `${p}: ngày sinh`);
      push(Boolean(s.workplace?.trim()), gaps, `${p}: nơi công tác`);
      push(Boolean(s.title?.trim()), gaps, `${p}: chức danh`);
      push(Boolean(s.qualification?.trim()), gaps, `${p}: trình độ`);
      push(Boolean(s.supportContent?.trim()), gaps, `${p}: nội dung hỗ trợ`);
    });
  }
  push(String(a.submissionDay || '').length > 0, gaps, 'Đơn: Ngày ký (ngày)');
  push(String(a.submissionMonth || '').length > 0, gaps, 'Đơn: Ngày ký (tháng)');
  push(Boolean(a.submissionYear?.trim()), gaps, 'Đơn: Ngày ký (năm)');
  return gaps;
}

/**
 * Tab « Xác nhận đóng góp » — ô cam kết chữ ký số.
 * Requires every field on báo cáo + đơn (including PDF minh chứng) and prior honesty ticks on those two tabs.
 */
export function collectContributionDigitalSignaturePrerequisiteGaps(
  report: InitiativeFormState,
  application: ApplicationFormState | StoredApplicationForm,
): string[] {
  const gaps = [...collectReportTabHonestyGaps(report), ...collectApplicationTabHonestyGaps(application)];
  if (!report.honestyConfirmed) {
    gaps.push('Báo cáo: cần tick ô cam kết trung thực ở cuối tab Báo cáo.');
  }
  if (!application.honestyConfirmed) {
    gaps.push('Đơn: cần tick ô cam kết trung thực ở cuối tab Đơn.');
  }
  return gaps;
}

/** Review tab — « Gửi tới Ban quản trị »: full dossier + contribution signature already saved. */
export function collectApplicantSubmitToAdminPrerequisiteGaps(
  report: InitiativeFormState,
  application: ApplicationFormState | StoredApplicationForm,
  contributionDigitalSignatureConfirmed: boolean,
): string[] {
  const gaps = collectContributionDigitalSignaturePrerequisiteGaps(report, application);
  if (!contributionDigitalSignatureConfirmed) {
    gaps.push('Xác nhận đóng góp: cần tick ô cam kết trung thực ở tab Xác nhận tỷ lệ đóng góp trước khi gửi.');
  }
  return gaps;
}

/** Toast body: newline-separated missing items (Sonner renders reasonably). */
export function formatApplicantPrerequisiteToastDescription(gaps: string[]): string {
  const uniq = [...new Set(gaps)];
  return uniq.slice(0, 16).join('\n') + (uniq.length > 16 ? `\n… và ${uniq.length - 16} mục khác` : '');
}
