import React, { useCallback, useEffect, useMemo, useState } from "react";
import "../../styles/ptw-document-form.css";
import { flushSync } from "react-dom";
import { formatPermitValidity } from "../../context/PermitValidityContext.jsx";
import PageHeader from "../../components/common/PageHeader.jsx";
import DataTable from "../../components/common/DataTable.jsx";
import ErrorBanner from "../../components/common/ErrorBanner.jsx";
import PtwDocumentSectionPreview from "../../components/form/PtwDocumentSectionPreview.jsx";
import PtwFormDocument from "../../components/form/PtwFormDocument.jsx";
import useMasterData from "../../hooks/useMasterData.js";
import { listForms } from "../../services/formsApi.js";
import { listPermits, listSubmissions } from "../../services/permitsApi.js";
import {
  loadPermitPreview
} from "../../utils/permitPreviewHelpers.js";
import { printPermitForms } from "../../utils/permitPrint.js";
import { parseNavFromHash, writeNavHash } from "../../utils/ptwNavUrl.js";

function readPermitIdFromHash() {
  const { params } = parseNavFromHash();
  const raw = params.permitId;
  const parsed = Number(raw);
  return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
}

function readPreviewStepFromHash() {
  const { params } = parseNavFromHash();
  const raw = params.previewStep;
  return raw != null && String(raw).trim() !== "" ? String(raw).trim() : null;
}

function PreviewStepDocument({ step, questionTypeOptions, permitNumber, formTypes = [] }) {
  if (!step?.sections?.length) {
    return <p className="swi-muted">No content for this step.</p>;
  }

  return (
    <PtwFormDocument
      jobTypeName={step.documentTitle || step.label || "PERMIT"}
      permitNumber={permitNumber}
      jobColor={step.jobColourCode}
    >
      {step.sections.map((entry, index) => (
        <PtwDocumentSectionPreview
          key={`${entry.submissionId}-${entry.section.section_id}-${index}`}
          section={entry.section}
          sectionKind={entry.sectionKind}
          questions={entry.questions}
          questionTypeOptions={questionTypeOptions}
          answers={entry.answers}
          mediaByQuestion={entry.mediaByQuestion}
          sectionMedia={entry.sectionMedia}
          skipped={entry.skipped}
          formMeta={step.formMeta || (step.type === "audit" ? { form_type_name: "Audit" } : null)}
          formTypes={formTypes}
        />
      ))}
    </PtwFormDocument>
  );
}

export default function AdminPermitPreviewPage({ onNavigate }) {
  const { data } = useMasterData();
  const [permits, setPermits] = useState([]);
  const [submissionCountByPermit, setSubmissionCountByPermit] = useState({});
  const [selectedPermitId, setSelectedPermitId] = useState(() => readPermitIdFromHash());
  const [preview, setPreview] = useState(null);
  const [stepIndex, setStepIndex] = useState(0);
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(false);
  const [loadingPermits, setLoadingPermits] = useState(true);
  const [printing, setPrinting] = useState(false);
  const [printAllMounted, setPrintAllMounted] = useState(false);

  const jobTypes = useMemo(
    () => (Array.isArray(data.ptw_job_type) ? data.ptw_job_type : []),
    [data.ptw_job_type]
  );
  const questionTypeOptions = useMemo(
    () =>
      (data.ptw_question_type || []).map((row) => ({
        value: String(row.question_type_id),
        label: row.question_type || `#${row.question_type_id}`
      })),
    [data.ptw_question_type]
  );
  const permitStatuses = useMemo(
    () => (Array.isArray(data.ptw_permit_status) ? data.ptw_permit_status : []),
    [data.ptw_permit_status]
  );
  const statusNameById = useMemo(
    () =>
      Object.fromEntries(
        permitStatuses.map((row) => [
          String(row.permit_status_id),
          row.permit_status_name || `#${row.permit_status_id}`
        ])
      ),
    [permitStatuses]
  );

  const steps = preview?.steps || [];
  const currentStep = steps[stepIndex] || null;
  const isFirstStep = stepIndex <= 0;
  const isLastStep = stepIndex >= steps.length - 1;

  const syncStepToHash = useCallback((permitId, stepId, { replace = false } = {}) => {
    if (!permitId) return;
    writeNavHash(
      "permit-preview",
      {
        permitId: String(permitId),
        ...(stepId ? { previewStep: stepId } : {})
      },
      { replace }
    );
  }, []);

  const loadPermitList = useCallback(async () => {
    setLoadingPermits(true);
    try {
      const [permitRows, submissionRows] = await Promise.all([
        listPermits(),
        listSubmissions()
      ]);
      const counts = {};
      for (const row of Array.isArray(submissionRows) ? submissionRows : []) {
        const pid = Number(row.permit_id);
        if (!Number.isFinite(pid) || pid <= 0) continue;
        counts[pid] = (counts[pid] || 0) + 1;
      }
      const withSubmissions = (Array.isArray(permitRows) ? permitRows : []).filter(
        (row) => (counts[Number(row.permit_id)] || 0) > 0
      );
      setSubmissionCountByPermit(counts);
      setPermits(withSubmissions);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setLoadingPermits(false);
    }
  }, []);

  const loadPreview = useCallback(async (permitId, preferredStepId = null) => {
    const pid = Number(permitId);
    if (!Number.isFinite(pid) || pid <= 0) {
      setPreview(null);
      setStepIndex(0);
      return;
    }

    setLoading(true);
    setError("");
    try {
      const forms = await listForms();
      const result = await loadPermitPreview(pid, {
        forms,
        jobTypes,
        formTypes: data.ptw_form_type || [],
        questionTypeOptions
      });
      setPreview(result);

      const nextSteps = result.steps || [];
      let nextIndex = 0;
      if (preferredStepId) {
        const found = nextSteps.findIndex((step) => step.id === preferredStepId);
        if (found >= 0) nextIndex = found;
      }
      setStepIndex(nextIndex);
      syncStepToHash(pid, nextSteps[nextIndex]?.id, { replace: true });
    } catch (err) {
      setPreview(null);
      setStepIndex(0);
      setError(err?.response?.data?.message || err.message);
    } finally {
      setLoading(false);
    }
  }, [jobTypes, questionTypeOptions, syncStepToHash]);

  useEffect(() => {
    loadPermitList();
  }, [loadPermitList]);

  useEffect(() => {
    const fromHash = readPermitIdFromHash();
    if (fromHash) {
      setSelectedPermitId(fromHash);
    }
  }, []);

  useEffect(() => {
    if (selectedPermitId) {
      loadPreview(selectedPermitId, readPreviewStepFromHash());
    } else {
      setPreview(null);
      setStepIndex(0);
    }
  }, [selectedPermitId, loadPreview]);

  function selectPermit(permitId) {
    const validId = Number.isFinite(Number(permitId)) && Number(permitId) > 0
      ? Number(permitId)
      : null;
    setSelectedPermitId(validId);
    setStepIndex(0);
    if (validId) {
      onNavigate?.("permit-preview", { permitId: validId });
    }
  }

  function handlePermitChange(event) {
    const nextId = Number(event.target.value);
    selectPermit(Number.isFinite(nextId) && nextId > 0 ? nextId : null);
  }

  const permitListColumns = useMemo(
    () => [
      {
        key: "permit_number",
        label: "Permit No.",
        render: (row) => row.permit_number || `PTW-${row.permit_id}`
      },
      {
        key: "permit_status_id",
        label: "Status",
        render: (row) =>
          statusNameById[String(row.permit_status_id)] || "—"
      },
      {
        key: "submission_count",
        label: "Submissions",
        render: (row) => submissionCountByPermit[Number(row.permit_id)] || 0
      },
      {
        key: "valid_until",
        label: "Valid until",
        render: (row) =>
          row.valid_until ? formatPermitValidity(row.valid_until) : "Not started"
      }
    ],
    [statusNameById, submissionCountByPermit]
  );

  function goToStep(nextIndex) {
    if (!steps.length) return;
    const clamped = Math.max(0, Math.min(nextIndex, steps.length - 1));
    setStepIndex(clamped);
    if (selectedPermitId && steps[clamped]) {
      syncStepToHash(selectedPermitId, steps[clamped].id);
    }
  }

  async function handlePrint(scope) {
    if (!preview || !steps.length || printing) return;
    setPrinting(true);
    setError("");
    const printAll = scope === "all";
    try {
      if (printAll) {
        flushSync(() => setPrintAllMounted(true));
        await new Promise((resolve) => requestAnimationFrame(() => resolve()));
      }
      await printPermitForms(scope);
    } catch (err) {
      setError(err?.message || "Could not open print preview.");
    } finally {
      setPrinting(false);
      if (printAll) {
        window.addEventListener(
          "afterprint",
          () => setPrintAllMounted(false),
          { once: true }
        );
      } else {
        setPrintAllMounted(false);
      }
    }
  }

  const selectedPermit = preview?.permit || permits.find(
    (row) => Number(row.permit_id) === Number(selectedPermitId)
  );
  const statusName = selectedPermit
    ? statusNameById[String(selectedPermit.permit_status_id)] || "—"
    : "";
  const permitNumber =
    preview?.permit?.permit_number ||
    selectedPermit?.permit_number ||
    "";

  return (
    <div className="portal-page portal-page--document-full ptw-permit-preview-page">
      <PageHeader
        title="Submitted forms"
        subtitle="Each form page shows the permit form plus audits, handovers, and handback below it."
        showBack
        backLabel="Back"
        onBack={() => onNavigate?.("permits-submissions")}
        actions={(
          <>
            <button
              type="button"
              className="swi-btn swi-btn--ghost ptw-no-print"
              disabled={loading || !selectedPermitId}
              onClick={() => loadPreview(selectedPermitId, currentStep?.id)}
            >
              {loading ? "Refreshing…" : "Refresh"}
            </button>
            {preview && steps.length ? (
              <>
                <button
                  type="button"
                  className="swi-btn swi-btn--ghost ptw-no-print"
                  disabled={loading || printing}
                  onClick={() => handlePrint("current")}
                >
                  {printing ? "Preparing…" : "Print this page"}
                </button>
                <button
                  type="button"
                  className="swi-btn swi-btn--primary ptw-no-print"
                  disabled={loading || printing || steps.length <= 1}
                  onClick={() => handlePrint("all")}
                  title={steps.length <= 1 ? "Only one page in this permit" : undefined}
                >
                  {printing ? "Preparing…" : "Print all pages"}
                </button>
              </>
            ) : null}
          </>
        )}
      />

      <ErrorBanner message={error} />

      <section className="ptw-permit-preview-picker ptw-no-print">
        <label className="ptw-permit-preview-picker__field" htmlFor="ptw-preview-permit-select">
          <span className="ptw-permit-preview-picker__label">Permit number</span>
          <select
            id="ptw-preview-permit-select"
            className="swi-input ptw-permit-preview-picker__select"
            value={selectedPermitId ?? ""}
            disabled={loadingPermits}
            onChange={handlePermitChange}
          >
            <option value="">
              {loadingPermits
                ? "Loading permits…"
                : permits.length
                  ? "Select a permit…"
                  : "No submitted permits yet"}
            </option>
            {permits.map((row) => (
              <option key={row.permit_id} value={row.permit_id}>
                {row.permit_number || `PTW-${row.permit_id}`}
                {" "}
                ({submissionCountByPermit[Number(row.permit_id)] || 0} submission
                {(submissionCountByPermit[Number(row.permit_id)] || 0) === 1 ? "" : "s"})
              </option>
            ))}
          </select>
        </label>
      </section>

      {!selectedPermitId ? (
        <section className="ptw-permit-preview-list ptw-no-print">
          <div className="ptw-permit-preview-list__head">
            <h2 className="ptw-permit-preview-list__title">Permits with submitted forms</h2>
            <p className="ptw-permit-preview-list__desc">
              Select a permit below to open its submitted forms preview.
            </p>
          </div>
          {loadingPermits ? (
            <p className="swi-muted">Loading permit list…</p>
          ) : (
            <DataTable
              columns={permitListColumns}
              rows={permits}
              keyField="permit_id"
              emptyMessage="No permits with submitted forms yet. Submit a permit from Permits & Submissions first."
              onRowClick={(row) => selectPermit(row.permit_id)}
            />
          )}
        </section>
      ) : null}

      {loading ? (
        <p className="swi-muted ptw-permit-preview-loading ptw-no-print">Loading submitted forms…</p>
      ) : null}

      {!loading && selectedPermitId && preview ? (
        <>
          <section className="ptw-permit-preview-summary ptw-no-print">
            <div className="ptw-permit-preview-summary__head">
              <div>
                <h2 className="ptw-permit-preview-summary__number">
                  {preview.permit.permit_number || `PTW-${preview.permit.permit_id}`}
                </h2>
                <p className="ptw-permit-preview-summary__meta">
                  Permit #{preview.permit.permit_id}
                  {statusName ? <> · {statusName}</> : null}
                </p>
              </div>
              <span className="ptw-permit-preview-summary__count">
                {preview.submissionCount} submission{preview.submissionCount === 1 ? "" : "s"}
                · {preview.sectionCount} section{preview.sectionCount === 1 ? "" : "s"}
                · {steps.length} page{steps.length === 1 ? "" : "s"}
              </span>
            </div>
            <dl className="ptw-permit-preview-summary__validity">
              <div>
                <dt>Valid from</dt>
                <dd>
                  {preview.permit.valid_from
                    ? formatPermitValidity(preview.permit.valid_from)
                    : "—"}
                </dd>
              </div>
              <div>
                <dt>Valid until</dt>
                <dd>
                  {preview.permit.valid_until
                    ? formatPermitValidity(preview.permit.valid_until)
                    : "—"}
                </dd>
              </div>
            </dl>
          </section>

          {steps.length ? (
            <>
              <nav className="ptw-permit-preview-steps ptw-no-print" aria-label="Preview sequence">
                <ol className="ptw-permit-preview-steps__list">
                  {steps.map((step, index) => (
                    <li key={step.id} className="ptw-permit-preview-steps__item">
                      <button
                        type="button"
                        className={`ptw-permit-preview-steps__btn${
                          index === stepIndex ? " ptw-permit-preview-steps__btn--active" : ""
                        }`}
                        onClick={() => goToStep(index)}
                        aria-current={index === stepIndex ? "step" : undefined}
                      >
                        <span className="ptw-permit-preview-steps__index">{index + 1}</span>
                        <span className="ptw-permit-preview-steps__label">{step.label}</span>
                      </button>
                    </li>
                  ))}
                </ol>
              </nav>

              <div className="ptw-print-permit-meta" aria-hidden="true">
                <p className="ptw-print-permit-meta__title">
                  {preview.permit.permit_number || `PTW-${preview.permit.permit_id}`}
                  {statusName ? ` · ${statusName}` : ""}
                </p>
                <p className="ptw-print-permit-meta__validity">
                  Valid from{" "}
                  {preview.permit.valid_from
                    ? formatPermitValidity(preview.permit.valid_from)
                    : "—"}
                  {" · "}
                  Valid until{" "}
                  {preview.permit.valid_until
                    ? formatPermitValidity(preview.permit.valid_until)
                    : "—"}
                </p>
              </div>

              <div className="ptw-permit-preview-documents ptw-print-current-sheet">
                <PreviewStepDocument
                  step={currentStep}
                  questionTypeOptions={questionTypeOptions}
                  permitNumber={permitNumber}
                  formTypes={data.ptw_form_type || []}
                />
              </div>

              {printAllMounted ? (
                <div className="ptw-print-all-stack" aria-hidden="true">
                  {steps.map((step) => (
                    <div key={step.id} className="ptw-print-sheet">
                      <p className="ptw-print-sheet__label">{step.label}</p>
                      <PreviewStepDocument
                        step={step}
                        questionTypeOptions={questionTypeOptions}
                        permitNumber={permitNumber}
                        formTypes={data.ptw_form_type || []}
                      />
                    </div>
                  ))}
                </div>
              ) : null}

              <div className="ptw-permit-preview-nav ptw-no-print">
                <button
                  type="button"
                  className="swi-btn swi-btn--ghost"
                  disabled={isFirstStep}
                  onClick={() => goToStep(stepIndex - 1)}
                >
                  Previous
                </button>
                <span className="ptw-permit-preview-nav__status">
                  Page {stepIndex + 1} of {steps.length}
                  {currentStep?.label ? <> · {currentStep.label}</> : null}
                </span>
                <button
                  type="button"
                  className="swi-btn swi-btn--primary"
                  disabled={isLastStep}
                  onClick={() => goToStep(stepIndex + 1)}
                >
                  Next
                </button>
              </div>
            </>
          ) : null}
        </>
      ) : null}

      {!loading && selectedPermitId && !preview && !error ? (
        <p className="swi-muted ptw-no-print">No submitted forms found for this permit.</p>
      ) : null}

    </div>
  );
}
