import { listQuestions, loadFormForFill } from "../services/formsApi.js";
import { findLifecycleForm } from "./jobTypeHelpers.js";
import {
  isAuthorizationQuestionType,
  isFillableTextQuestion,
  resolveQuestionTypeKind,
  QUESTION_TYPE_KIND
} from "./questionTypeHelpers.js";
import {
  SECTION_KIND,
  resolveSectionKind,
  sortSections
} from "./sectionTypeHelpers.js";

function normalize(value) {
  return String(value || "").trim().toLowerCase();
}

function formatDisplayTitle(title, type) {
  const raw = String(title || "").trim();
  if (raw) return raw;
  if (type === "handover") return "Handover";
  if (type === "handback") return "Handback";
  if (type === "audit") return "AUDIT (At least one per shift)";
  return "Lifecycle";
}

function lifecycleSectionKind(type) {
  if (type === "handover") return SECTION_KIND.HANDOVER;
  if (type === "handback") return SECTION_KIND.HANDBACK;
  if (type === "audit") return SECTION_KIND.AUDIT;
  return SECTION_KIND.STANDARD;
}

export function collectSectionQuestions(sections) {
  return sortSections(sections).flatMap((section) =>
    Array.isArray(section?.questions) ? section.questions : []
  );
}

async function loadFormWithQuestions(formId) {
  const formDef = await loadFormForFill(Number(formId));
  const sections = sortSections(formDef?.sections);
  const questions = collectSectionQuestions(sections);
  return { formDef, sections, questions };
}

/**
 * When a lifecycle form section exists but has no mapped questions, resolve
 * questions from the shared catalog using lifecycle naming conventions.
 */
function pickCatalogQuestionsForLifecycle(catalog, type, questionTypeOptions = []) {
  const list = Array.isArray(catalog) ? catalog : [];

  if (type === "handover") {
    return list
      .filter((q) => {
        const label = normalize(q.question);
        if (
          isAuthorizationQuestionType(
            q.question_type_id,
            questionTypeOptions,
            q.question_type
          )
        ) {
          return label.includes("new ") || label.includes("permit accepter");
        }
        if (isFillableTextQuestion(q, questionTypeOptions)) {
          return (
            label.includes("handover") ||
            label.includes("hand over") ||
            (label.includes("hand") && label.includes("confirm"))
          );
        }
        return false;
      })
      .sort((a, b) => Number(a.question_id) - Number(b.question_id));
  }

  if (type === "handback") {
    return list
      .filter((q) => {
        const kind = resolveQuestionTypeKind(
          q.question_type_id,
          questionTypeOptions,
          q.question_type
        );
        if (kind !== QUESTION_TYPE_KIND.YES_NO) return false;
        const label = normalize(q.question);
        return (
          label.includes("qualified") ||
          label.includes("induction") ||
          label.includes("risk assessment")
        );
      })
      .sort((a, b) => Number(a.question_id) - Number(b.question_id));
  }

  if (type === "audit") {
    return list
      .filter((q) => {
        const label = normalize(q.question);
        return (
          label === "who" ||
          label === "date" ||
          label.startsWith("action ")
        );
      })
      .sort((a, b) => Number(a.question_id) - Number(b.question_id));
  }

  return [];
}

async function resolveQuestionsForLifecycleForm(formId, type, questionTypeOptions) {
  const { formDef, sections, questions: mappedQuestions } =
    await loadFormWithQuestions(formId);

  if (mappedQuestions.length) {
    return { formDef, sections, questions: mappedQuestions };
  }

  const catalog = await listQuestions();
  const catalogQuestions = pickCatalogQuestionsForLifecycle(
    catalog,
    type,
    questionTypeOptions
  );
  if (catalogQuestions.length) {
    return { formDef, sections, questions: catalogQuestions };
  }

  return { formDef, sections, questions: [] };
}

export async function resolveLifecycleFormDefinition({
  type,
  submissionRows,
  forms,
  jobTypes,
  formTypes = [],
  questionTypeOptions = []
}) {
  const lifecycleForm = findLifecycleForm(forms, jobTypes, type, formTypes);
  if (lifecycleForm) {
    const { formDef, sections, questions } = await resolveQuestionsForLifecycleForm(
      lifecycleForm.form_id,
      type,
      questionTypeOptions
    );

    if (!questions.length) {
      const hint =
        type === "audit"
          ? "Map audit section questions (WHO, DATE, Action rows) in Section Management, or run seed_ptw_audit_form_structure.sql."
          : "Map questions to its section in Section Management, or add handover/handback questions to the question catalog.";
      throw new Error(
        `Form "${lifecycleForm.title || lifecycleForm.form_id}" has no questions configured. ${hint}`
      );
    }

    return {
      formId: Number(lifecycleForm.form_id),
      formDef: { ...formDef, form_type_id: lifecycleForm.form_type_id ?? formDef?.form_type_id },
      displayTitle: formatDisplayTitle(lifecycleForm.title, type),
      sections,
      questions
    };
  }

  const openingSubmission =
    (submissionRows || []).find(
      (row) => String(row.submission_role || "").toLowerCase() === "opening"
    ) || (submissionRows || []).find((row) => row.form_id);
  if (!openingSubmission?.form_id) {
    throw new Error("Could not resolve opening form for this permit.");
  }

  const openingFormId = Number(openingSubmission.form_id);
  const { sections, questions } = await resolveQuestionsForLifecycleForm(
    openingFormId,
    type,
    questionTypeOptions
  );

  const preferredKind = lifecycleSectionKind(type);
  const targetSection = sections.find((s) => resolveSectionKind(s) === preferredKind);
  const sectionQuestions = Array.isArray(targetSection?.questions)
    ? targetSection.questions
    : [];

  const resolvedQuestions = sectionQuestions.length ? sectionQuestions : questions;

  if (!resolvedQuestions.length) {
    throw new Error(
      `No ${type} form found in the database. Link a form to a ${type} job type in Form Management, or add a ${type} section to the opening form.`
    );
  }

  return {
    formId: openingFormId,
    formDef: null,
    displayTitle: formatDisplayTitle(targetSection?.title, type),
    sections: targetSection ? [targetSection] : sections,
    questions: resolvedQuestions
  };
}
