import React, { useCallback, useEffect, useMemo, useState } from "react";
import PageHeader from "../common/PageHeader.jsx";
import DataTable from "../common/DataTable.jsx";
import ErrorBanner from "../common/ErrorBanner.jsx";
import EntityModal from "../common/EntityModal.jsx";

const TABS = { CREATE: "create", LIST: "list" };

/**
 * Shared Create / View All layout for PTW Form Administration pages.
 */
export default function PtwMgmtPage({
  title,
  subtitle,
  keyField,
  labels,
  blankDraft,
  buildPayload,
  draftFromRow,
  loadDraftForUpdate,
  loadRowForUpdate,
  normalizeRow,
  listFn,
  getFn,
  createFn,
  updateFn,
  validateDraft,
  renderFields,
  renderDetail,
  renderUpdateExtra,
  onViewRow,
  onUpdateRow,
  buildColumns,
  extraCreateContent = null,
  extraTabs = [],
  replaceCreatePanel = null
}) {
  const [activeTab, setActiveTab] = useState(TABS.CREATE);
  const [rows, setRows] = useState([]);
  const [error, setError] = useState("");
  const [saving, setSaving] = useState(false);
  const [createDraft, setCreateDraft] = useState(blankDraft);
  const [viewRow, setViewRow] = useState(null);
  const [updateRow, setUpdateRow] = useState(null);
  const [editDraft, setEditDraft] = useState(blankDraft);
  const [successPopup, setSuccessPopup] = useState(null);
  const [listLoading, setListLoading] = useState(false);
  const [viewLoading, setViewLoading] = useState(false);
  const [updateLoading, setUpdateLoading] = useState(false);

  async function loadRows() {
    setListLoading(true);
    try {
      setError("");
      const list = await listFn();
      const normalized = (Array.isArray(list) ? list : [])
        .map(normalizeRow)
        .filter(Boolean);
      setRows(normalized);
      return normalized;
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
      return null;
    } finally {
      setListLoading(false);
    }
  }

  useEffect(() => {
    loadRows();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  function switchTab(tab) {
    setViewRow(null);
    setUpdateRow(null);
    setActiveTab(tab);
    if (tab === TABS.LIST) {
      loadRows();
    }
  }

  const isExtraTab = extraTabs.some((t) => t.id === activeTab);

  const openView = useCallback(async (row) => {
    const id = Number(row?.[keyField]);
    if (!Number.isFinite(id) || id <= 0) {
      setError(`Cannot open ${labels.entitySingular}: invalid id.`);
      return;
    }
    setError("");
    setViewRow(normalizeRow(row) || row);
    setViewLoading(true);
    try {
      const fresh = await getFn(id);
      setViewRow(normalizeRow(fresh) || row);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setViewLoading(false);
    }
  }, [getFn, keyField, labels.entitySingular, normalizeRow]);

  const reloadView = useCallback(async () => {
    if (!viewRow) return;
    const id = Number(viewRow[keyField]);
    if (!Number.isFinite(id) || id <= 0) return;
    setViewLoading(true);
    try {
      setError("");
      const fresh = await getFn(id);
      setViewRow(normalizeRow(fresh) || viewRow);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setViewLoading(false);
    }
  }, [viewRow, getFn, keyField, normalizeRow]);

  const openUpdate = useCallback(async (row) => {
    const normalized = normalizeRow(row) || row;
    setUpdateRow(normalized);
    setError("");
    try {
      if (loadDraftForUpdate) {
        const draft = await loadDraftForUpdate(normalized);
        setEditDraft(draft);
      } else {
        setEditDraft(draftFromRow(normalized));
      }
      if (loadRowForUpdate) {
        setUpdateLoading(true);
        const enriched = await loadRowForUpdate(normalized);
        setUpdateRow(normalizeRow(enriched) || normalized);
      }
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
      setEditDraft(draftFromRow(normalized));
    } finally {
      setUpdateLoading(false);
    }
  }, [draftFromRow, loadDraftForUpdate, loadRowForUpdate, normalizeRow]);

  const reloadUpdate = useCallback(async () => {
    if (!updateRow || !loadRowForUpdate) return;
    setUpdateLoading(true);
    try {
      setError("");
      const enriched = await loadRowForUpdate(updateRow);
      setUpdateRow(normalizeRow(enriched) || updateRow);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setUpdateLoading(false);
    }
  }, [updateRow, loadRowForUpdate, normalizeRow]);

  const handleCreate = async (e) => {
    e.preventDefault();
    const validationError = validateDraft(createDraft);
    if (validationError) {
      setError(validationError);
      return;
    }
    setSaving(true);
    try {
      setError("");
      await createFn(buildPayload(createDraft));
      setCreateDraft({ ...blankDraft });
      await loadRows();
      setActiveTab(TABS.LIST);
      setSuccessPopup(labels.createSuccess);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setSaving(false);
    }
  };

  const handleUpdate = async () => {
    if (!updateRow) return;
    const validationError = validateDraft(editDraft);
    if (validationError) {
      setError(validationError);
      return;
    }
    const id = Number(updateRow[keyField]);
    if (!Number.isFinite(id) || id <= 0) {
      setError(`Cannot update ${labels.entitySingular}: invalid id.`);
      return;
    }
    setSaving(true);
    try {
      setError("");
      await updateFn(id, buildPayload(editDraft));
      await loadRows();
      setUpdateRow(null);
      setSuccessPopup(labels.updateSuccess);
    } catch (err) {
      setError(err?.response?.data?.message || err.message);
    } finally {
      setSaving(false);
    }
  };

  const handleViewRow = onViewRow || openView;
  const handleUpdateRow = onUpdateRow || openUpdate;

  const columns = useMemo(
    () => buildColumns({ openView: handleViewRow, openUpdate: handleUpdateRow, rows }),
    [buildColumns, handleViewRow, handleUpdateRow, rows]
  );

  const viewTitle = viewRow?.title ?? viewRow?.question ?? labels.viewModalTitle;
  const inSubView = Boolean(viewRow || updateRow);

  function handleSubViewBack() {
    setViewRow(null);
    setUpdateRow(null);
    setEditDraft(blankDraft);
  }

  return (
    <div className="portal-page ptw-mgmt-page">
      <PageHeader
        title={title}
        subtitle={subtitle}
        showBack={inSubView ? true : undefined}
        onBack={inSubView ? handleSubViewBack : undefined}
        backLabel={inSubView ? "Back to list" : "Back"}
      />
      <ErrorBanner message={error} />

      <div className="ptw-mgmt-shell">
        <div className="ptw-mgmt-tabs" role="tablist">
          <button
            type="button"
            role="tab"
            aria-selected={activeTab === TABS.CREATE}
            className={`ptw-mgmt-tab${activeTab === TABS.CREATE ? " is-active" : ""}`}
            onClick={() => switchTab(TABS.CREATE)}
          >
            {labels.createTab}
          </button>
          <button
            type="button"
            role="tab"
            aria-selected={activeTab === TABS.LIST}
            className={`ptw-mgmt-tab${activeTab === TABS.LIST ? " is-active" : ""}`}
            onClick={() => switchTab(TABS.LIST)}
          >
            {labels.listTab}
            {rows.length > 0 ? <span className="ptw-mgmt-tab__count">{rows.length}</span> : null}
          </button>
          {extraTabs.map((tab) => (
            <button
              key={tab.id}
              type="button"
              role="tab"
              aria-selected={activeTab === tab.id}
              className={`ptw-mgmt-tab${activeTab === tab.id ? " is-active" : ""}`}
              onClick={() => switchTab(tab.id)}
            >
              {tab.label}
            </button>
          ))}
        </div>

        <div className="ptw-mgmt-body">
          {isExtraTab ? extraTabs.find((t) => t.id === activeTab)?.render() : null}

          {!isExtraTab && activeTab === TABS.CREATE && replaceCreatePanel ? (
            replaceCreatePanel({
              onComplete: async () => {
                await loadRows();
                setActiveTab(TABS.LIST);
                setSuccessPopup(labels.createSuccess);
              }
            })
          ) : null}

          {!isExtraTab && activeTab === TABS.CREATE && !replaceCreatePanel ? (
            <form className="ptw-mgmt-card" onSubmit={handleCreate}>
              <div className="ptw-mgmt-card__header">
                <div>
                  <h2 className="ptw-mgmt-card__title">{labels.createHeading}</h2>
                  <p className="ptw-mgmt-card__desc">{labels.createDesc}</p>
                </div>
              </div>

              <div className="ptw-mgmt-section">
                <h3 className="ptw-mgmt-section__title">{labels.createSectionTitle}</h3>
                {renderFields({ draft: createDraft, setDraft: setCreateDraft, mode: "create" })}
              </div>

              <div className="ptw-mgmt-card__footer">
                <button type="submit" className="swi-btn swi-btn--primary" disabled={saving}>
                  {saving ? labels.createSaving : labels.createButton}
                </button>
                <button
                  type="button"
                  className="swi-btn swi-btn--ghost"
                  onClick={() => setCreateDraft({ ...blankDraft })}
                  disabled={saving}
                >
                  {labels.clearButton}
                </button>
              </div>

              {extraCreateContent}
            </form>
          ) : null}

          {!isExtraTab && activeTab === TABS.LIST ? (
            <div className="ptw-mgmt-card ptw-mgmt-card--list">
              <div className="ptw-mgmt-card__header ptw-mgmt-card__header--row">
                <div>
                  <h2 className="ptw-mgmt-card__title">{labels.listHeading}</h2>
                  <p className="ptw-mgmt-card__desc">{labels.listDesc}</p>
                </div>
                <button
                  type="button"
                  className="swi-btn swi-btn--ghost"
                  onClick={loadRows}
                  disabled={listLoading}
                >
                  {listLoading ? "Refreshing…" : "Refresh"}
                </button>
              </div>
              <div className="ptw-mgmt-list-meta">
                <span>
                  {listLoading
                    ? `Loading ${labels.entityPlural}…`
                    : `${rows.length} ${rows.length === 1 ? labels.entitySingular : labels.entityPlural} found`}
                </span>
              </div>
              {listLoading && rows.length === 0 ? (
                <p className="ptw-muted ptw-mgmt-list-loading">
                  {`Fetching ${labels.entityPlural}…`}
                </p>
              ) : null}
              <DataTable
                columns={columns}
                rows={rows}
                keyField={keyField}
                emptyMessage={labels.emptyList}
              />
            </div>
          ) : null}
        </div>
      </div>

      {!onViewRow ? (
        <EntityModal
          open={Boolean(viewRow)}
          title={viewRow ? viewTitle : labels.viewModalTitle}
          subtitle={
            viewRow
              ? `${labels.entitySingular} #${viewRow[keyField]}`
              : undefined
          }
          size="wide"
          variant="detail"
          onClose={() => setViewRow(null)}
        >
          {viewRow ? (
            viewLoading ? (
              <div className="ptw-entity-modal__loading">
                <span className="ptw-entity-modal__spinner" aria-hidden="true" />
                <p>{labels.viewLoading}</p>
              </div>
            ) : (
              renderDetail({ row: viewRow, reloadView })
            )
          ) : null}
        </EntityModal>
      ) : null}

      {!onUpdateRow ? (
        <EntityModal
          open={Boolean(updateRow)}
          title={labels.updateModalTitle}
          subtitle={
            updateRow ? `${labels.entitySingular} #${updateRow[keyField]}` : undefined
          }
          size={renderUpdateExtra ? "wide" : "default"}
          variant={renderUpdateExtra ? "detail" : "default"}
          onClose={() => setUpdateRow(null)}
        >
          {updateRow ? (
            updateLoading ? (
              <div className="ptw-entity-modal__loading">
                <span className="ptw-entity-modal__spinner" aria-hidden="true" />
                <p>Loading…</p>
              </div>
            ) : (
              <>
                {renderFields({ draft: editDraft, setDraft: setEditDraft, mode: "edit" })}
                {renderUpdateExtra?.({ updateRow, reloadUpdate })}
                <div className="ptw-row-actions ptw-entity-modal__update-actions">
                  <button
                    type="button"
                    className="swi-btn swi-btn--primary"
                    onClick={handleUpdate}
                    disabled={saving}
                  >
                    {saving ? "Saving…" : "Save changes"}
                  </button>
                  <button
                    type="button"
                    className="swi-btn swi-btn--ghost"
                    onClick={() => setUpdateRow(null)}
                  >
                    Cancel
                  </button>
                </div>
              </>
            )
          ) : null}
        </EntityModal>
      ) : null}

      <EntityModal
        open={Boolean(successPopup)}
        title="Success"
        onClose={() => setSuccessPopup(null)}
      >
        <p className="ptw-mgmt-success-msg">{successPopup}</p>
        <button type="button" className="swi-btn swi-btn--primary" onClick={() => setSuccessPopup(null)}>
          OK
        </button>
      </EntityModal>
    </div>
  );
}
