import { useEffect, useMemo, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { apiGet, apiPut } from "../lib/api";
import type {
  ActiveCatalogSummary,
  QuarterKey,
  SampleDetail,
  SensitivityResult,
} from "../lib/types";

type GroupState = Record<string, SensitivityResult | undefined>;

function quarterIdentity(sample: SampleDetail, quarterKey: QuarterKey) {
  const quarter = sample.quarters.find((entry) => entry.quarterKey === quarterKey);
  if (!quarter) {
    return quarterKey;
  }
  return quarter.pathogenBusinessKey || quarter.customPathogenName || quarter.pathogenName || quarterKey;
}

export default function AntibiogramPage() {
  const { sampleId } = useParams();
  const navigate = useNavigate();

  const [catalogs, setCatalogs] = useState<ActiveCatalogSummary | null>(null);
  const [sample, setSample] = useState<SampleDetail | null>(null);
  const [groupState, setGroupState] = useState<Record<string, GroupState>>({});
  const [message, setMessage] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    async function load() {
      if (!sampleId) {
        return;
      }
      try {
        const [catalogResponse, sampleResponse] = await Promise.all([
          apiGet<ActiveCatalogSummary>("/catalogs/summary"),
          apiGet<SampleDetail>(`/samples/${sampleId}`),
        ]);
        setCatalogs(catalogResponse);
        setSample(sampleResponse);

        const nextState: Record<string, GroupState> = {};
        sampleResponse.antibiogramTargets.forEach((referenceQuarter) => {
          const existingGroup =
            sampleResponse.antibiograms.find((entry) => entry.quarterKey === referenceQuarter) ??
            sampleResponse.antibiograms.find((entry) => entry.inheritedFromQuarter === referenceQuarter);
          nextState[referenceQuarter] = {};
          existingGroup?.entries.forEach((entry) => {
            nextState[referenceQuarter][entry.antibioticBusinessKey] = entry.result;
          });
        });
        setGroupState(nextState);
      } catch (loadError) {
        setMessage((loadError as Error).message);
      }
    }

    void load();
  }, [sampleId]);

  const groups = useMemo(() => {
    if (!sample) {
      return [];
    }
    return sample.antibiogramTargets.map((referenceQuarter) => {
      const identity = quarterIdentity(sample, referenceQuarter);
      const reference = sample.quarters.find((quarter) => quarter.quarterKey === referenceQuarter);
      const inherited = sample.quarters.filter(
        (quarter) =>
          quarter.quarterKey !== referenceQuarter &&
          quarterIdentity(sample, quarter.quarterKey) === identity &&
          quarter.requiresAntibiogram,
      );
      return { referenceQuarter, reference, inherited };
    });
  }, [sample]);

  function updateResult(
    referenceQuarter: QuarterKey,
    antibioticBusinessKey: string,
    result: SensitivityResult,
  ) {
    setGroupState((current) => ({
      ...current,
      [referenceQuarter]: {
        ...current[referenceQuarter],
        [antibioticBusinessKey]:
          current[referenceQuarter]?.[antibioticBusinessKey] === result ? undefined : result,
      },
    }));
  }

  async function handleSave() {
    if (!sampleId || !sample) {
      return;
    }

    setSaving(true);
    setMessage(null);

    try {
      const response = await apiPut<SampleDetail>(`/samples/${sampleId}/antibiogram`, {
        groups: groups.map((group) => ({
          referenceQuarter: group.referenceQuarter,
          entries: Object.entries(groupState[group.referenceQuarter] ?? {})
            .filter((entry): entry is [string, SensitivityResult] => Boolean(entry[1]))
            .map(([antibioticBusinessKey, result]) => ({
              antibioticBusinessKey,
              result,
            })),
        })),
      });
      navigate(`/samples/${response.id}/${response.routeSegment}`);
    } catch (saveError) {
      setMessage((saveError as Error).message);
    } finally {
      setSaving(false);
    }
  }

  if (!sample || !catalogs) {
    return <div className="empty-state">Antibiogramm wird geladen ...</div>;
  }

  return (
    <div className="page-stack">
      <section className="section-card section-card--hero">
        <div>
          <p className="eyebrow">Antibiogramm</p>
          <h3>Probe {sample.sampleNumber}</h3>
          <p className="muted-text">
            Nur Viertel mit bakteriellem Wachstum werden angezeigt. Identische Erreger werden
            automatisch zusammengefasst.
          </p>
        </div>

        {sample.antibiogramEditable ? null : (
          <div className="alert alert--warning">
            Das Antibiogramm ist in diesem Bearbeitungsstand nur noch lesbar.
          </div>
        )}

        {message ? <div className="alert alert--error">{message}</div> : null}
      </section>

      {!groups.length ? (
        <div className="empty-state">Fuer diese Probe ist kein Antibiogramm erforderlich.</div>
      ) : (
        groups.map((group) => (
          <section key={group.referenceQuarter} className="section-card">
            <div className="section-card__header">
              <div>
                <p className="eyebrow">{group.reference?.label}</p>
                <h3>{group.reference?.customPathogenName || group.reference?.pathogenName || "Erreger"}</h3>
              </div>
              {group.inherited.length ? (
                <div className="info-chip">
                  Gilt ebenfalls fuer {group.inherited.map((entry) => entry.label).join(", ")}
                </div>
              ) : null}
            </div>

            <div className="table-shell">
              <table className="data-table">
                <thead>
                  <tr>
                    <th>Antibiotikum</th>
                    <th>S</th>
                    <th>I</th>
                    <th>R</th>
                  </tr>
                </thead>
                <tbody>
                  {catalogs.antibiotics.map((antibiotic) => (
                    <tr key={antibiotic.businessKey}>
                      <td>
                        <strong>{antibiotic.name}</strong>
                        <small className="table-subtext">{antibiotic.code ?? "ANT"}</small>
                      </td>
                      {(["SENSITIVE", "INTERMEDIATE", "RESISTANT"] as SensitivityResult[]).map((result) => (
                        <td key={result}>
                          <button
                            type="button"
                            className={`matrix-button ${
                              groupState[group.referenceQuarter]?.[antibiotic.businessKey] === result
                                ? "is-selected"
                                : ""
                            }`}
                            onClick={() => updateResult(group.referenceQuarter, antibiotic.businessKey, result)}
                            disabled={!sample.antibiogramEditable}
                          >
                            {result === "SENSITIVE" ? "S" : result === "INTERMEDIATE" ? "I" : "R"}
                          </button>
                        </td>
                      ))}
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </section>
        ))
      )}

      <div className="page-actions">
        <button
          type="button"
          className="accent-button"
          onClick={() => void handleSave()}
          disabled={saving || !sample.antibiogramEditable}
        >
          {saving ? "Speichern ..." : "Speichern"}
        </button>
      </div>
    </div>
  );
}
