/** Match rows from ptw_job_type (e.g. GENERAL, HOT WORK). */

export const DEFAULT_PTW_JOB_COLOR = "#ffff00";

const HEX_COLOR_RE = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/;

export function resolveJobTypeColor(jobTypes = [], jobTypeId) {
  const id = Number(jobTypeId);
  if (!Number.isFinite(id) || id <= 0) return DEFAULT_PTW_JOB_COLOR;

  const row = (Array.isArray(jobTypes) ? jobTypes : []).find(
    (jt) => Number(jt.job_type_id) === id
  );
  const code = String(row?.job_colour_code || "").trim();
  if (HEX_COLOR_RE.test(code)) return code;
  return DEFAULT_PTW_JOB_COLOR;
}

export function resolveJobTypeColorFromForm(form, jobTypes = []) {
  return resolveJobTypeColor(jobTypes, form?.job_type_id);
}

export function normalizeJobTypeName(name) {
  return String(name || "").trim().toLowerCase();
}

export function isGeneralJobType(jobType) {
  const name = normalizeJobTypeName(jobType?.job_type_name);
  return (
    name === "general" ||
    name === "general ptw" ||
    name.includes("general permit")
  );
}

/** GENERAL is always the mandatory first permit (job_type_id 1 in hse.ptw_job_type). */
export function findGeneralJobType(jobTypes = []) {
  const list = Array.isArray(jobTypes) ? jobTypes : [];
  const byName = list.find(isGeneralJobType);
  if (byName) return byName;
  return list.find((jt) => Number(jt.job_type_id) === 1) ?? null;
}

export function specializedJobTypes(jobTypes = []) {
  return (Array.isArray(jobTypes) ? jobTypes : []).filter((jt) => !isGeneralJobType(jt));
}

export function findFormForJobType(forms = [], jobTypeId) {
  const id = Number(jobTypeId);
  if (!Number.isFinite(id) || id <= 0) return null;
  const matches = (Array.isArray(forms) ? forms : []).filter(
    (f) => Number(f.job_type_id) === id
  );
  if (!matches.length) return null;
  return matches.sort((a, b) => Number(b.form_id) - Number(a.form_id))[0];
}

function lifecycleNameMatches(name, type) {
  const normalized = normalizeJobTypeName(name);
  if (type === "handover") {
    return normalized.includes("handover") || normalized.includes("hand over");
  }
  if (type === "handback") {
    return normalized.includes("handback") || normalized.includes("hand back");
  }
  if (type === "audit") {
    return normalized === "audit" || normalized.includes("audit");
  }
  return false;
}

/** Form with ptw_form_type = Audit (shift audit lifecycle). */
export function findAuditForm(forms = [], formTypes = []) {
  const list = Array.isArray(forms) ? forms : [];
  const types = Array.isArray(formTypes) ? formTypes : [];
  const auditType = types.find((row) => lifecycleNameMatches(row?.form_type_name, "audit"));
  if (!auditType) return null;
  const typeId = Number(auditType.form_type_id);
  const matches = list.filter((form) => Number(form.form_type_id) === typeId);
  if (!matches.length) return null;
  return matches.sort((a, b) => Number(b.form_id) - Number(a.form_id))[0];
}

/** Exported for permit preview role inference when `submission_role` is missing in DB. */
export function inferLifecycleTypeFromName(name) {
  if (lifecycleNameMatches(name, "handover")) return "handover";
  if (lifecycleNameMatches(name, "handback")) return "handback";
  if (lifecycleNameMatches(name, "audit")) return "audit";
  return null;
}

/** Job type row for handover or handback workflows. */
export function findLifecycleJobType(jobTypes = [], type) {
  const list = Array.isArray(jobTypes) ? jobTypes : [];
  return list.find((jt) => lifecycleNameMatches(jt?.job_type_name, type)) ?? null;
}

/** Dedicated lifecycle form from ptw_form_details (job type / form type link, then title match). */
export function findLifecycleForm(forms = [], jobTypes = [], type, formTypes = []) {
  if (type === "audit") {
    const byFormType = findAuditForm(forms, formTypes);
    if (byFormType) return byFormType;
  }

  const list = Array.isArray(forms) ? forms : [];
  const jobType = findLifecycleJobType(jobTypes, type);
  if (jobType) {
    const linked = findFormForJobType(list, jobType.job_type_id);
    if (linked) return linked;
  }
  const matches = list.filter((form) => lifecycleNameMatches(form?.title, type));
  if (!matches.length) return null;
  return matches.sort((a, b) => Number(b.form_id) - Number(a.form_id))[0];
}
