import React, { useCallback, useEffect, useMemo, useState } from "react";
import "../../styles/ptw-form-fill-hub.css";
import "../../styles/ptw-document-form.css";
import { useAuth } from "../../context/AuthContext.jsx";
import { formatPermitValidity, usePermitValidity } from "../../context/PermitValidityContext.jsx";
import PageHeader from "../../components/common/PageHeader.jsx";
import ErrorBanner from "../../components/common/ErrorBanner.jsx";
import PtwDocumentSection from "../../components/form/PtwDocumentSection.jsx";
import PtwFormDocument from "../../components/form/PtwFormDocument.jsx";
import useMasterData from "../../hooks/useMasterData.js";
import { listForms } from "../../services/formsApi.js";
import { createSubmission, getPermit, listSubmissions } from "../../services/permitsApi.js";
import { findLifecycleJobType, resolveJobTypeColor, DEFAULT_PTW_JOB_COLOR } from "../../utils/jobTypeHelpers.js";
import {
  resolveLifecycleFormDefinition
} from "../../utils/lifecycleFormHelpers.js";
import { SECTION_KIND } from "../../utils/sectionTypeHelpers.js";
import { collectAuditDisplayQuestions } from "../../utils/auditSectionHelpers.js";
import {
  QUESTION_TYPE_KIND,
  getSignoffRoleLabel,
  isAuthorizationQuestionType,
  isDeclarationTextQuestion,
  isImageQuestionType,
  parseSignoffAnswer,
  resolveQuestionTypeKind,
  serializeSignoffAnswer,
  validateSignoffAnswer
} from "../../utils/questionTypeHelpers.js";

const VALID_LIFECYCLE_TYPES = new Set(["handover", "handback", "audit"]);

function readAnswerValue(answers, questionId) {
  return answers[questionId] ?? answers[String(questionId)] ?? "";
}

function readMediaFiles(mediaByQuestion, questionId) {
  return mediaByQuestion[questionId] || mediaByQuestion[String(questionId)] || [];
}

function typeOptionsForQuestion(question, questionTypeOptions) {
  if (question?.question_type) {
    return [
      {
        value: String(question.question_type_id ?? ""),
        label: question.question_type
      }
    ];
  }
  return questionTypeOptions;
}

function isAnswerEmpty(question, answerValue, mediaFiles, questionTypeOptions) {
  const typeOpts = typeOptionsForQuestion(question, questionTypeOptions);
  const kind = resolveQuestionTypeKind(
    question.question_type_id,
    typeOpts,
    question.question_type
  );
  const hasMedia = Array.isArray(mediaFiles) && mediaFiles.length > 0;

  if (
    isAuthorizationQuestionType(
      question.question_type_id,
      typeOpts,
      question.question_type
    )
  ) {
    return Boolean(
      validateSignoffAnswer(
        answerValue,
        mediaFiles.filter(Boolean)[0] || null,
        getSignoffRoleLabel(question)
      )
    );
  }

  if (kind === QUESTION_TYPE_KIND.IMAGE || isImageQuestionType(question.question_type_id, typeOpts)) {
    return !hasMedia;
  }

  return !String(answerValue ?? "").trim() && !hasMedia;
}

function buildQuestionAnswers(questions, answers, mediaByQuestion, questionTypeOptions) {
  return (questions || []).map((q) => {
    const qid = q.question_id;
    const files = readMediaFiles(mediaByQuestion, qid).filter(Boolean);
    const typeOpts = typeOptionsForQuestion(q, questionTypeOptions);
    const kind = resolveQuestionTypeKind(
      q.question_type_id,
      typeOpts,
      q.question_type
    );

    if (
      isAuthorizationQuestionType(q.question_type_id, typeOpts, q.question_type)
    ) {
      const raw = readAnswerValue(answers, qid);
      return {
        question_id: qid,
        is_media: files.length > 0 ? 1 : 0,
        answer_value: raw ? serializeSignoffAnswer(parseSignoffAnswer(raw)) : null
      };
    }

    const isMedia =
      files.length > 0 ||
      kind === QUESTION_TYPE_KIND.IMAGE ||
      isImageQuestionType(q.question_type_id, typeOpts)
        ? 1
        : 0;
    let answerValue = readAnswerValue(answers, qid);
    if (isMedia && !String(answerValue).trim() && files.length) {
      answerValue = files.map((f) => f.name).join(", ");
    }
    return {
      question_id: qid,
      is_media: isMedia,
      answer_value: answerValue || null
    };
  });
}

function buildMediaMap(questions, mediaByQuestion) {
  const mediaMap = {};
  for (const q of questions || []) {
    const files = readMediaFiles(mediaByQuestion, q.question_id).filter(Boolean);
    if (files.length) {
      mediaMap[q.question_id] = files;
    }
  }
  return mediaMap;
}

export default function AdminPermitLifecyclePage({ type, onDone }) {
  const isValidType = VALID_LIFECYCLE_TYPES.has(type);
  const { auth } = useAuth();
  const { data } = useMasterData();
  const { clearWorkflowView, clearActivePermit, setActivePermit } = usePermitValidity();

  const [permit, setPermit] = useState(null);
  const [formId, setFormId] = useState(null);
  const [formMeta, setFormMeta] = useState(null);
  const [formTitle, setFormTitle] = useState("");
  const [sections, setSections] = useState([]);
  const [questions, setQuestions] = useState([]);
  const [answers, setAnswers] = useState({});
  const [mediaByQuestion, setMediaByQuestion] = useState({});
  const [error, setError] = useState("");
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [success, setSuccess] = useState(false);

  const permitId = useMemo(() => Number(permit?.permit_id), [permit?.permit_id]);

  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 jobTypes = useMemo(
    () => (Array.isArray(data.ptw_job_type) ? data.ptw_job_type : []),
    [data.ptw_job_type]
  );

  const sectionTitle =
    formTitle ||
    (type === "handover" ? "Handover" : type === "handback" ? "Handback" : "Audit");
  const submitLabel = `Submit ${sectionTitle.toLowerCase()}`;

  const lifecycleJobTypeName = useMemo(() => {
    if (type === "audit") return "AUDIT";
    const jobType = findLifecycleJobType(jobTypes, type);
    return jobType?.job_type_name || sectionTitle.toUpperCase();
  }, [jobTypes, type, sectionTitle]);

  const lifecycleJobColor = useMemo(() => {
    if (type === "audit") return DEFAULT_PTW_JOB_COLOR;
    const jobType = findLifecycleJobType(jobTypes, type);
    return resolveJobTypeColor(jobTypes, jobType?.job_type_id);
  }, [jobTypes, type]);

  const sectionKind =
    type === "handover"
      ? SECTION_KIND.HANDOVER
      : type === "handback"
        ? SECTION_KIND.HANDBACK
        : SECTION_KIND.AUDIT;

  const documentSection = useMemo(() => {
    const base = sections[0];
    if (base) {
      return { ...base, title: base.title || sectionTitle, questions };
    }
    return { section_id: 0, title: sectionTitle, questions };
  }, [sections, sectionTitle, questions]);

  const activeQuestions = useMemo(() => {
    if (type !== "audit") return questions;
    return collectAuditDisplayQuestions(questions);
  }, [type, questions]);

  const loadContext = useCallback(async () => {
    if (!isValidType) return;
    setLoading(true);
    setError("");
    setAnswers({});
    setMediaByQuestion({});
    setQuestions([]);
    try {
      const workflowPermitId = Number(
        sessionStorage.getItem("ptw_lifecycle_permit_id") ||
          JSON.parse(sessionStorage.getItem("ptw_active_permit") || "{}")?.permitId
      );
      if (!Number.isFinite(workflowPermitId) || workflowPermitId <= 0) {
        throw new Error("No active permit selected for this workflow.");
      }

      const [permitRow, submissionRows, formRows] = await Promise.all([
        getPermit(workflowPermitId),
        listSubmissions({ permit_id: workflowPermitId }),
        listForms()
      ]);

      setPermit(permitRow);

      if (!permitRow?.valid_from) {
        throw new Error("This permit has no active validity window; submit the general permit first.");
      }
      if (Number(permitRow.permit_status_id) === 3) {
        throw new Error("This permit is already closed.");
      }

      const lifecycleForm = await resolveLifecycleFormDefinition({
        type,
        submissionRows,
        forms: Array.isArray(formRows) ? formRows : [],
        jobTypes,
        formTypes: data.ptw_form_type || [],
        questionTypeOptions
      });

      setFormId(lifecycleForm.formId);
      setFormMeta(lifecycleForm.formDef ?? (lifecycleForm.formId ? { form_id: lifecycleForm.formId } : null));
      setFormTitle(lifecycleForm.displayTitle);
      setSections(lifecycleForm.sections);
      setQuestions(lifecycleForm.questions);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
      setPermit(null);
      setFormId(null);
      setFormMeta(null);
      setFormTitle("");
      setSections([]);
      setQuestions([]);
    } finally {
      setLoading(false);
    }
  }, [isValidType, type, jobTypes, questionTypeOptions, data.ptw_form_type]);

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

  useEffect(() => {
    if (permit?.permit_id) {
      sessionStorage.setItem("ptw_lifecycle_permit_id", String(permit.permit_id));
    }
  }, [permit?.permit_id]);

  function setAnswer(questionId, value) {
    setAnswers((prev) => ({ ...prev, [questionId]: value }));
  }

  function setMedia(questionId, files) {
    setMediaByQuestion((prev) => ({ ...prev, [questionId]: files }));
  }

  function validateForm() {
    const missing = activeQuestions.filter((q) => {
      if (isDeclarationTextQuestion(q, questionTypeOptions)) {
        return false;
      }
      return isAnswerEmpty(
        q,
        readAnswerValue(answers, q.question_id),
        readMediaFiles(mediaByQuestion, q.question_id),
        questionTypeOptions
      );
    });

    if (missing.length) {
      return `Please complete all required fields (${missing.length} remaining).`;
    }
    return null;
  }

  async function handleSubmit(event) {
    event.preventDefault();
    if (!isValidType || !permitId || !formId || !activeQuestions.length) return;

    const validationError = validateForm();
    if (validationError) {
      setError(validationError);
      return;
    }

    const payload = {
      permit_id: permitId,
      form_id: formId,
      submission_role: type,
      answers: buildQuestionAnswers(activeQuestions, answers, mediaByQuestion, questionTypeOptions)
    };
    const submitterId = Number(auth?.user?.user_id);
    if (Number.isFinite(submitterId) && submitterId > 0) {
      payload.submitter_id = submitterId;
    }

    const mediaMap = buildMediaMap(activeQuestions, mediaByQuestion);

    setSubmitting(true);
    setError("");
    try {
      const result = await createSubmission(payload, mediaMap, {});
      if (type === "handback") {
        clearActivePermit();
        sessionStorage.removeItem("ptw_lifecycle_permit_id");
      } else if (type === "handover" && result?.valid_from && result?.valid_until) {
        sessionStorage.removeItem(`ptw_expiry_warn_${permit.permit_id}`);
        setActivePermit({
          permitId: permit.permit_id,
          permitNumber: permit.permit_number,
          validFrom: result.valid_from,
          validUntil: result.valid_until
        });
      }
      setSuccess(true);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setSubmitting(false);
    }
  }

  function handleClose() {
    clearWorkflowView();
    sessionStorage.removeItem("ptw_lifecycle_permit_id");
    onDone?.();
  }

  if (!isValidType) {
    return <ErrorBanner message="Unknown permit lifecycle workflow." />;
  }

  if (success) {
    return (
      <div className="portal-page">
        <section className="ptw-form-fill-shell ptw-form-fill-result ptw-form-fill-result--success">
          <div className="ptw-form-fill-result__icon" aria-hidden="true">✓</div>
          <h2 className="ptw-form-fill-result__title">
            {type === "handback" ? "Permit closed" : `${sectionTitle} submitted`}
          </h2>
          <p className="ptw-form-fill-result__text">
            {permit?.permit_number ? (
              <>Permit <strong>{permit.permit_number}</strong> — {sectionTitle.toLowerCase()} recorded.</>
            ) : (
              <>{sectionTitle} recorded for this permit.</>
            )}
            {type === "handback" ? (
              <> This permit is now closed and cannot accept further submissions.</>
            ) : type === "audit" ? (
              <> You can record another audit for this shift while the permit remains active.</>
            ) : type === "handover" ? (
              <>
                {" "}
                The permit remains active — it can be handed over again before expiry.
                The new permit accepter will receive a notification in PTW.
              </>
            ) : (
              <> The permit remains active.</>
            )}
          </p>
          <button type="button" className="swi-btn swi-btn--primary" onClick={handleClose}>
            Back to PTW
          </button>
        </section>
      </div>
    );
  }

  return (
    <div className="portal-page ptw-form-fill-page ptw-lifecycle-page portal-page--document-full">
      <PageHeader
        title={type === "handover" ? "Handover" : type === "handback" ? "Handback" : "Shift audit"}
        subtitle={
          type === "audit"
            ? "Complete the audit form for an active permit (at least one per shift)."
            : `Complete the ${sectionTitle.toLowerCase()} form for an active permit.`
        }
        onBack={handleClose}
      />
      <ErrorBanner message={error} />

      {loading ? (
        <p className="swi-muted">Loading permit…</p>
      ) : permit ? (
        <form className="ptw-form-fill ptw-form-fill--document" onSubmit={handleSubmit}>
          <PtwFormDocument
            jobTypeName={lifecycleJobTypeName}
            permitNumber={permit.permit_number || ""}
            jobColor={lifecycleJobColor}
          >
            <div className="ptw-lifecycle-form__validity">
              <span>Valid from: <strong>{formatPermitValidity(permit.valid_from)}</strong></span>
              <span>Valid until: <strong>{formatPermitValidity(permit.valid_until)}</strong></span>
            </div>

            <PtwDocumentSection
              section={documentSection}
              sectionKind={sectionKind}
              questions={questions}
              questionTypeOptions={questionTypeOptions}
              answers={answers}
              setAnswer={setAnswer}
              mediaByQuestion={mediaByQuestion}
              setMedia={setMedia}
              formMeta={formMeta || (formId ? { form_id: formId } : null)}
              formTypes={data.ptw_form_type || []}
            />
          </PtwFormDocument>

          <div className="ptw-doc-footer">
            <button type="submit" className="swi-btn swi-btn--primary" disabled={submitting}>
              {submitting ? "Submitting…" : submitLabel}
            </button>
          </div>
        </form>
      ) : null}
    </div>
  );
}
