import React, { useCallback, useEffect, useMemo, useState } from "react";
import PtwMgmtPage from "../../components/admin/PtwMgmtPage.jsx";
import useMasterData from "../../hooks/useMasterData.js";
import QuestionTypeFormatPanel from "./components/QuestionTypeFormatPanel.jsx";
import {
  createQuestion,
  createQuestionOption,
  deleteQuestionOption,
  getQuestion,
  listQuestionOptions,
  listQuestions,
  listSections,
  mapSectionQuestion,
  updateQuestion
} from "../../services/formsApi.js";
import {
  isAuthorizationQuestionType,
  isImageQuestionType,
  normalizeOptionsArray,
  resolveQuestionTypeKind,
  typeNeedsOptions
} from "../../utils/questionTypeHelpers.js";
import { mgmtActionColumn } from "../../utils/ptwMgmtHelpers.jsx";

const blankQuestion = {
  question: "",
  question_type_id: "",
  allows_media: false,
  options: [],
  section_id: ""
};

function buildQuestionPayload(draft, questionTypeOptions = []) {
  const payload = {};
  if (draft.question?.trim()) payload.question = draft.question.trim();
  if (draft.question_type_id) payload.question_type_id = Number(draft.question_type_id);
  const forceMedia =
    isImageQuestionType(draft.question_type_id, questionTypeOptions) ||
    isAuthorizationQuestionType(draft.question_type_id, questionTypeOptions);
  payload.allows_media = forceMedia || draft.allows_media ? 1 : 0;
  payload.options = normalizeOptionsArray(draft.options);
  if (draft.section_id) payload.section_id = Number(draft.section_id);
  return payload;
}

function draftFromRow(row) {
  return {
    question: row.question ?? "",
    question_type_id:
      row.question_type_id != null ? String(row.question_type_id) : "",
    allows_media: Boolean(row.allows_media),
    options: [],
    section_id: ""
  };
}

function normalizeQuestionRow(row) {
  if (!row || typeof row !== "object") return null;
  const questionId = Number(row.question_id);
  return {
    ...row,
    question_id: Number.isFinite(questionId) ? questionId : row.question_id,
    question_type_id:
      row.question_type_id != null && row.question_type_id !== ""
        ? Number(row.question_type_id)
        : null,
    allows_media: Boolean(row.allows_media)
  };
}

async function insertOptionsForQuestion(questionId, options) {
  const values = normalizeOptionsArray(options);
  if (!questionId || !values.length) return;
  await Promise.all(
    values.map((value) =>
      createQuestionOption({ question_id: questionId, _options: value })
    )
  );
}

async function replaceOptionsForQuestion(questionId, options) {
  const existing = await listQuestionOptions({ question_id: questionId });
  const rows = Array.isArray(existing) ? existing : [];
  await Promise.all(
    rows.map((row) => {
      const id = row.question_options_id;
      if (id != null) return deleteQuestionOption(id);
      return Promise.resolve();
    })
  );
  await insertOptionsForQuestion(questionId, options);
}

async function createWithOptions(payload) {
  const { options, section_id, ...questionPayload } = payload;
  const created = await createQuestion(questionPayload);
  const questionId = created?.insertedId ?? created?.question_id ?? null;
  if (questionId && options?.length) {
    await insertOptionsForQuestion(questionId, options);
  }
  if (questionId && section_id) {
    await mapSectionQuestion({
      section_id: Number(section_id),
      question_id: Number(questionId)
    });
  }
  return created;
}

async function updateWithOptions(questionId, payload) {
  const { options, section_id, ...questionPayload } = payload;
  const updated = await updateQuestion(questionId, questionPayload);
  await replaceOptionsForQuestion(questionId, options ?? []);
  return updated;
}

async function fetchOptionsForQuestion(questionId) {
  const rows = await listQuestionOptions({ question_id: questionId });
  return (Array.isArray(rows) ? rows : [])
    .map((row) => row._options ?? row.option ?? "")
    .filter(Boolean);
}

async function getQuestionWithOptions(questionId) {
  const question = await getQuestion(questionId);
  const options = await fetchOptionsForQuestion(questionId);
  return { ...question, options };
}

function handleTypeChange(prev, typeId, questionTypeOptions) {
  const kind = resolveQuestionTypeKind(typeId, questionTypeOptions);
  const next = { ...prev, question_type_id: typeId };

  if (typeNeedsOptions(kind)) {
    next.options = prev.options?.length ? prev.options : [""];
  } else {
    next.options = [];
  }

  if (isImageQuestionType(typeId, questionTypeOptions)) {
    next.allows_media = true;
  }

  if (isAuthorizationQuestionType(typeId, questionTypeOptions)) {
    next.allows_media = true;
    next.options = prev.options?.length ? prev.options : [""];
  }

  return next;
}

function QuestionFields({ draft, setDraft, questionTypeOptions, sectionOptions = [] }) {
  const kind = resolveQuestionTypeKind(draft.question_type_id, questionTypeOptions);
  const hideMediaCheckbox =
    isImageQuestionType(draft.question_type_id, questionTypeOptions) ||
    isAuthorizationQuestionType(draft.question_type_id, questionTypeOptions);

  return (
    <div className="ptw-mgmt-form-grid">
      <label className="ptw-mgmt-field ptw-mgmt-field--full">
        <span className="ptw-mgmt-field__label">
          Question <em className="ptw-mgmt-required">*</em>
        </span>
        <textarea
          className="ptw-mgmt-input ptw-mgmt-textarea"
          rows={4}
          value={draft.question}
          onChange={(e) => setDraft((prev) => ({ ...prev, question: e.target.value }))}
          placeholder="Enter the question text"
        />
      </label>
      <label className="ptw-mgmt-field">
        <span className="ptw-mgmt-field__label">Question type</span>
        <select
          className="ptw-mgmt-input ptw-mgmt-select"
          value={draft.question_type_id}
          onChange={(e) =>
            setDraft((prev) =>
              handleTypeChange(prev, e.target.value, questionTypeOptions)
            )
          }
        >
          <option value="">Select question type</option>
          {questionTypeOptions.map((opt) => (
            <option key={opt.value} value={opt.value}>
              {opt.label}
            </option>
          ))}
        </select>
      </label>
      {!hideMediaCheckbox ? (
        <label className="ptw-mgmt-field ptw-mgmt-field--check">
          <span className="ptw-mgmt-check">
            <input
              type="checkbox"
              checked={Boolean(draft.allows_media)}
              onChange={(e) =>
                setDraft((prev) => ({ ...prev, allows_media: e.target.checked }))
              }
            />
            <span>Allow image/video upload</span>
          </span>
        </label>
      ) : hideMediaCheckbox &&
        isAuthorizationQuestionType(draft.question_type_id, questionTypeOptions) ? (
        <div className="ptw-mgmt-field ptw-mgmt-field--check">
          <span className="ptw-mgmt-check ptw-mgmt-check--muted">
            <input type="checkbox" checked disabled readOnly />
            <span>Signature capture enabled for sign-off rows</span>
          </span>
        </div>
      ) : (
        <div className="ptw-mgmt-field ptw-mgmt-field--check">
          <span className="ptw-mgmt-check ptw-mgmt-check--muted">
            <input type="checkbox" checked disabled readOnly />
            <span>Image/video upload enabled</span>
          </span>
        </div>
      )}
      <div className="ptw-mgmt-field ptw-mgmt-field--full">
        <QuestionTypeFormatPanel
          kind={kind}
          typeId={draft.question_type_id}
          questionTypeOptions={questionTypeOptions}
          options={draft.options}
          onOptionsChange={(options) =>
            setDraft((prev) => ({ ...prev, options: options || [] }))
          }
        />
      </div>
      <label className="ptw-mgmt-field">
        <span className="ptw-mgmt-field__label">Link to section (optional)</span>
        <select
          className="ptw-mgmt-input ptw-mgmt-select"
          value={draft.section_id}
          onChange={(e) => setDraft((prev) => ({ ...prev, section_id: e.target.value }))}
        >
          <option value="">No section (map later)</option>
          {sectionOptions.map((opt) => (
            <option key={opt.value} value={opt.value}>
              {opt.label}
            </option>
          ))}
        </select>
      </label>
    </div>
  );
}

function QuestionDetailView({ row, questionTypeName }) {
  const options = Array.isArray(row.options) ? row.options : [];
  const optionLabels = options.map((o) =>
    typeof o === "string" ? o : o._options ?? o.option ?? ""
  ).filter(Boolean);

  return (
    <dl className="ptw-key-value ptw-mgmt-detail">
      <dt>Question ID</dt>
      <dd>{row.question_id}</dd>
      <dt>Question</dt>
      <dd>{row.question || "—"}</dd>
      <dt>Question type</dt>
      <dd>{questionTypeName[String(row.question_type_id)] || row.question_type_id || "—"}</dd>
      <dt>Allows media</dt>
      <dd>{row.allows_media ? "Yes" : "No"}</dd>
      {optionLabels.length > 0 ? (
        <>
          <dt>Options</dt>
          <dd>
            <ul className="ptw-mgmt-detail-options">
              {optionLabels.map((label, i) => (
                <li key={i}>{label}</li>
              ))}
            </ul>
          </dd>
        </>
      ) : null}
    </dl>
  );
}

export default function AdminQuestionManagementPage() {
  const { data } = useMasterData();
  const [sectionOptions, setSectionOptions] = useState([]);

  useEffect(() => {
    let mounted = true;
    (async () => {
      try {
        const sections = await listSections();
        if (mounted) {
          setSectionOptions(
            (Array.isArray(sections) ? sections : []).map((s) => ({
              value: String(s.section_id),
              label: `#${s.section_id} — ${s.title || "Untitled"}`
            }))
          );
        }
      } catch {
        /* optional */
      }
    })();
    return () => {
      mounted = false;
    };
  }, []);

  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 questionTypeName = useMemo(
    () => Object.fromEntries(questionTypeOptions.map((o) => [o.value, o.label])),
    [questionTypeOptions]
  );

  const validateDraft = useCallback(
    (draft) => {
      if (!draft.question?.trim()) return "Question is required.";
      const kind = resolveQuestionTypeKind(
        draft.question_type_id,
        questionTypeOptions
      );
      if (
        typeNeedsOptions(kind) &&
        !isAuthorizationQuestionType(draft.question_type_id, questionTypeOptions) &&
        !normalizeOptionsArray(draft.options).length
      ) {
        return "Add at least one option for this question type.";
      }
      return null;
    },
    [questionTypeOptions]
  );

  const loadDraftForUpdate = useCallback(
    async (row) => {
      const base = draftFromRow(row);
      const questionId = Number(row.question_id);
      if (!Number.isFinite(questionId) || questionId <= 0) return base;

      const optionValues = await fetchOptionsForQuestion(questionId);
      const kind = resolveQuestionTypeKind(
        base.question_type_id,
        questionTypeOptions
      );
      return {
        ...base,
        options: optionValues.length
          ? optionValues
          : typeNeedsOptions(kind)
            ? [""]
            : []
      };
    },
    [questionTypeOptions]
  );

  return (
    <PtwMgmtPage
      title="Question Management"
      subtitle="Create PTW questions and manage existing question definitions."
      keyField="question_id"
      labels={{
        createTab: "Create Question",
        listTab: "View All Questions",
        createHeading: "Create a new question",
        createDesc:
          "Define the question. Optionally link it to a section (saved in ptw_section_question_map).",
        createSectionTitle: "Question details",
        listHeading: "All questions",
        listDesc: "View or update any question from the list below.",
        entitySingular: "question",
        entityPlural: "questions",
        createButton: "Create question",
        createSaving: "Creating…",
        clearButton: "Clear form",
        createSuccess: "Question has been created successfully.",
        updateSuccess: "Question update has been completed.",
        emptyList:
          "No questions yet. Switch to Create Question to add your first question.",
        viewModalTitle: "View question",
        updateModalTitle: "Update question",
        viewLoading: "Loading question details…"
      }}
      blankDraft={blankQuestion}
      buildPayload={(draft) => buildQuestionPayload(draft, questionTypeOptions)}
      draftFromRow={draftFromRow}
      loadDraftForUpdate={loadDraftForUpdate}
      normalizeRow={normalizeQuestionRow}
      listFn={listQuestions}
      getFn={getQuestionWithOptions}
      createFn={createWithOptions}
      updateFn={updateWithOptions}
      validateDraft={validateDraft}
      renderFields={({ draft, setDraft, mode }) => (
        <QuestionFields
          draft={draft}
          setDraft={setDraft}
          questionTypeOptions={questionTypeOptions}
          sectionOptions={mode === "create" ? sectionOptions : []}
        />
      )}
      renderDetail={({ row }) => (
        <QuestionDetailView row={row} questionTypeName={questionTypeName} />
      )}
      buildColumns={({ openView, openUpdate }) => [
        { key: "question_id", label: "ID" },
        {
          key: "question",
          label: "Question",
          render: (r) => (
            <span className="ptw-mgmt-cell-clip">{r.question || "—"}</span>
          )
        },
        {
          key: "question_type_id",
          label: "Type",
          render: (r) => (
            <span className="ptw-mgmt-tag">
              {questionTypeName[String(r.question_type_id)] || "—"}
            </span>
          )
        },
        {
          key: "allows_media",
          label: "Media",
          render: (r) => (
            <span className="ptw-mgmt-tag ptw-mgmt-tag--muted">
              {r.allows_media ? "Yes" : "No"}
            </span>
          )
        },
        mgmtActionColumn({ openView, openUpdate })
      ]}
    />
  );
}
