import { useMemo, useState, type ReactNode } from 'react'
import { Link, useParams } from 'react-router-dom'
import { de } from '../strings/de'
import { getGerbil, updateGerbil } from '../api/gerbils'
import { listLitters as listLittersPaged } from '../api/litters'
import { listColorVarieties, listContacts, listEnclosures, listLitters } from '../api/lookups'
import { useApi, useMutation } from '../hooks/useApi'
import { formatDate, genderLabel, statusLabel } from '../format/labels'
import { ALL_TRAITS, TRAIT_CATEGORIES } from '../format/traits'
import { fromDisplayString, genotypeToFarbschlag, displayGenotypeSafe } from '../genetics'
import type { Gender, GerbilStatus } from '../api/types'
import FarbschlagImage from '../components/FarbschlagImage'
import GerbilAcquisitionSection from '../components/GerbilAcquisitionSection'
import GerbilHealthTab from '../components/GerbilHealthTab'
import GerbilPhotosTab from '../components/GerbilPhotosTab'
import GerbilProfilePhoto from '../components/GerbilProfilePhoto'
import GerbilWeightTab from '../components/GerbilWeightTab'
import ProvenanceDialog from '../components/ProvenanceDialog'
import ReportErrorDialog from '../components/ReportErrorDialog'
import { useGerbilName } from '../components/breederSuffix'
import { useToast } from '../components/toast'
import './rennmausakte.css'

type DetailTab = 'photos' | 'health' | 'weight'

// DESIGN (Rennmausakte): per-status colours for the hero status badge.
const STATUS_COLORS: Record<GerbilStatus, string> = {
  Breeding: '#5e8c5a',
  Pet: '#5a7da8',
  ForSale: '#c2703d',
  Deceased: '#8a847b',
  GivenAway: '#b08e5c',
}
const GENDER_SYMBOL: Record<Gender, string> = { unknown: '?', male: '♂', female: '♀' }

/** Parse a stored genotype string and derive its normalized form + Farbschlag. */
function describeGenotype(genotype: string | null): { display: string; farbschlag: string } | null {
  if (!genotype || !genotype.trim()) return null
  try {
    const g = fromDisplayString(genotype)
    return { display: displayGenotypeSafe(genotype), farbschlag: genotypeToFarbschlag(g) }
  } catch {
    return { display: displayGenotypeSafe(genotype), farbschlag: de.genetics.unknownFarbschlag }
  }
}

/** A labelled key/value row inside a card (semantic dt/dd, styled as a grid). */
function Kv({ label, children }: { label: string; children: ReactNode }) {
  return (
    <div className="ak-kv">
      <dt className="ak-kv-label">{label}</dt>
      <dd className="ak-kv-value">{children}</dd>
    </div>
  )
}

export default function GerbilDetailPage() {
  const t = de.pages.gerbils
  const gerbilName = useGerbilName()
  const toast = useToast()
  const { id = '' } = useParams()
  const [tab, setTab] = useState<DetailTab>('photos')
  const [reportOpen, setReportOpen] = useState(false)
  const [provenanceOpen, setProvenanceOpen] = useState(false)

  const gerbil = useApi(() => getGerbil(id), [id])
  const forSale = useMutation(() => updateGerbil(id, { status: 'ForSale' }))
  // FEAT-14: Charakterbogen (persisted on the Gerbil).
  const [charTraits, setCharTraits] = useState<string[]>([])
  const [charNote, setCharNote] = useState('')
  const [charInit, setCharInit] = useState<string | null>(null)
  // Charakter ist v. a. für lebende Bestandstiere relevant → bei Zucht/Liebhaber
  // aufgeklappt, sonst (Abgabe/Verstorben/Abgegeben) eingeklappt (manuell öffenbar).
  const [charExpanded, setCharExpanded] = useState(true)
  const saveCharacter = useMutation(() =>
    updateGerbil(id, { characterTraits: charTraits, characterNote: charNote.trim() || null }),
  )
  const colorVarieties = useApi(() => listColorVarieties(), [])
  const enclosures = useApi(() => listEnclosures(), [])
  const contacts = useApi(() => listContacts(), [])
  const litters = useApi(() => listLitters(), [])
  const parentLitters = useApi(
    () => listLittersPaged({ filter: `fatherId=${id}|motherId=${id}`, orderBy: 'date desc', pageSize: 50 }),
    [id],
  )

  const colorName = useMemo(
    () => new Map((colorVarieties.data ?? []).map((c) => [c.id, c.name])),
    [colorVarieties.data],
  )
  const enclosureName = useMemo(
    () => new Map((enclosures.data ?? []).map((e) => [e.id, e.name])),
    [enclosures.data],
  )
  const contactName = useMemo(
    () => new Map((contacts.data ?? []).map((c) => [c.id, c.name])),
    [contacts.data],
  )
  const litterName = useMemo(
    () => new Map((litters.data ?? []).map((l) => [l.id, l.name])),
    [litters.data],
  )

  // Parents come from the gerbil's own litter (litterId → litter.fatherId/motherId).
  // Fetch each parent gerbil for its name + link (mirrors WurfDetailPage).
  const ownLitterId = gerbil.data?.litterId ?? null
  const ownLitter = useMemo(
    () => (ownLitterId ? ((litters.data ?? []).find((l) => l.id === ownLitterId) ?? null) : null),
    [litters.data, ownLitterId],
  )
  const fatherId = ownLitter?.fatherId ?? null
  const motherId = ownLitter?.motherId ?? null
  const father = useApi(() => (fatherId ? getGerbil(fatherId) : Promise.resolve(null)), [fatherId])
  const mother = useApi(() => (motherId ? getGerbil(motherId) : Promise.resolve(null)), [motherId])

  // Character chips — toggle while preserving the catalog order (stable output).
  const selectedTraits = new Set(charTraits)
  const toggleTrait = (key: string) => {
    const next = new Set(selectedTraits)
    if (next.has(key)) next.delete(key)
    else next.add(key)
    setCharTraits(ALL_TRAITS.filter((tr) => next.has(tr.key)).map((tr) => tr.key))
  }

  if (gerbil.loading) return <p className="muted">{de.common.loading}</p>
  if (gerbil.error || !gerbil.data) {
    return (
      <section className="page">
        <p className="muted">{gerbil.error ?? t.detail.notFound}</p>
        <Link to="/rennmaeuse" className="btn">
          {t.detail.back}
        </Link>
      </section>
    )
  }

  const g = gerbil.data
  // Abgegebene/verstorbene Tiere sind nicht mehr im eigenen Bestand → kein Gehege.
  const showEnclosure = g.status !== 'Deceased' && g.status !== 'GivenAway'

  const geno = describeGenotype(g.genotype)
  const lookup = (map: Map<string, string>, key: string | null) => (key ? (map.get(key) ?? '—') : '—')
  const storedColorName = g.colorVarietyId ? (colorName.get(g.colorVarietyId) ?? null) : null

  // Geschwisterverpaarung: Vater und Mutter dieses Tiers sind Vollgeschwister —
  // erkennbar an gemeinsamer litterId ODER gleichem Geburtsdatum (starkes Indiz:
  // ein identisches Datum entsteht praktisch nur durch einen gemeinsamen Wurf,
  // und die Eltern-Würfe sind in den Daten nicht immer verknüpft).
  const isSiblingPairing =
    !!father.data &&
    !!mother.data &&
    father.data.id !== mother.data.id &&
    ((!!father.data.litterId && father.data.litterId === mother.data.litterId) ||
      (!!father.data.dateOfBirth && father.data.dateOfBirth === mother.data.dateOfBirth))

  const parentLink = (
    pid: string | null,
    p: Parameters<typeof gerbilName>[0] | null,
  ): ReactNode =>
    pid && p ? (
      <Link to={`/rennmaeuse/${pid}`}>{gerbilName(p) || de.pages.gerbils.nameless}</Link>
    ) : (
      de.pages.litters.detail.unknownParent
    )

  // Seed the character state once from the loaded gerbil (adjust-state-during-render).
  if (charInit !== g.id) {
    setCharInit(g.id)
    setCharTraits(g.characterTraits ?? [])
    setCharNote(g.characterNote ?? '')
    setCharExpanded(g.status === 'Breeding' || g.status === 'Pet')
  }

  return (
    <section className="ak">
      <div className="ak-hero">
        <GerbilProfilePhoto
          gerbilId={g.id}
          className="ak-herophoto"
          fallback={
            <div className="ak-herophoto ak-herophoto--empty" aria-hidden="true">
              🐭
            </div>
          }
        />
        <div className="ak-herobar">
          <Link to="/rennmaeuse" className="ak-back" aria-label={t.detail.back}>
            ‹
          </Link>
        </div>
        <div className="ak-heroover">
          <h1 className="ak-name">{gerbilName(g) || de.pages.gerbils.nameless}</h1>
          <span className="ak-statusbadge" style={{ color: STATUS_COLORS[g.status] }}>
            {statusLabel(g.status)}
          </span>
          {g.isResident === false && (
            <span className="ak-badge-extern" title={de.pages.gerbils.externalTitle}>
              {de.pages.gerbils.externalBadge}
            </span>
          )}
        </div>
      </div>

      <div className="ak-content">
        <div className="ak-facts">
          <span className="ak-fact">
            <span aria-hidden="true">{GENDER_SYMBOL[g.gender]}</span>
            {genderLabel(g.gender)}
            {g.isCastrated ? ' (Kastrat)' : ''}
          </span>
          {g.dateOfBirth && (
            <span className="ak-fact">
              <span aria-hidden="true">🎂</span>
              {formatDate(g.dateOfBirth)}
            </span>
          )}
          {storedColorName && (
            <span className="ak-fact">
              <span aria-hidden="true">🎨</span>
              {storedColorName}
            </span>
          )}
          {isSiblingPairing && (
            <span className="ak-fact ak-fact--sibling" title={t.detail.siblingPairingTitle}>
              <span aria-hidden="true">⚭</span>
              {t.detail.siblingPairing}
            </span>
          )}
        </div>

        <div className="ak-actions">
          <Link to={`/rennmaeuse/${g.id}/bearbeiten`} className="ak-btn primary">
            {t.detail.edit}
          </Link>
          <Link to={`/genetik?parent=${g.id}`} className="ak-btn">
            {t.detail.testMating}
          </Link>
          <Link to={`/rennmaeuse/${g.id}/stammbaum`} className="ak-btn">
            {de.pages.stammbaum.openButton}
          </Link>
          {g.status !== 'ForSale' && g.status !== 'Deceased' && (
            <button
              type="button"
              className="ak-btn"
              disabled={forSale.pending}
              onClick={async () => {
                const r = await forSale.run()
                if (r.ok) {
                  toast.success(de.common.saved)
                  gerbil.reload()
                } else {
                  toast.error(r.error)
                }
              }}
            >
              {de.pages.abgabe.markAction}
            </button>
          )}
          {g.status !== 'Deceased' && g.status !== 'GivenAway' && (
            <Link to={`/vertraege/neu?tiere=${g.id}`} className="ak-btn">
              {de.pages.vertraege.wizard.title}
            </Link>
          )}
          <button type="button" className="ak-btn" onClick={() => setProvenanceOpen(true)}>
            {de.provenance.button}
          </button>
          <button type="button" className="ak-btn" onClick={() => setReportOpen(true)}>
            {de.feedback.button}
          </button>
          <Link to="/rennmaeuse" className="ak-btn">
            {t.detail.back}
          </Link>
        </div>

        <section className="ak-card">
          <h2 className="ak-h2">{t.detail.masterData}</h2>
          <dl className="ak-kvlist">
            <Kv label={t.fields.gender}>
              {genderLabel(g.gender)}
              {g.isCastrated && <span style={{ marginLeft: '0.4rem', opacity: 0.8 }}>(Kastrat)</span>}
            </Kv>
            <Kv label={t.fields.status}>{statusLabel(g.status)}</Kv>
            <Kv label={t.fields.dateOfBirth}>{formatDate(g.dateOfBirth)}</Kv>
            {g.status === 'Deceased' && (
              <>
                <Kv label={t.fields.dateOfDeath}>{formatDate(g.dateOfDeath)}</Kv>
                <Kv label={t.fields.causeOfDeath}>{g.causeOfDeath || '—'}</Kv>
              </>
            )}
            {g.status === 'GivenAway' && (
              <Kv label={t.fields.goHomeDate}>{formatDate(g.goHomeDate)}</Kv>
            )}
            <Kv label={t.fields.colorVariety}>
              {storedColorName ? (
                <>
                  <FarbschlagImage name={storedColorName} size={22} />
                  {storedColorName}
                </>
              ) : (
                '—'
              )}
            </Kv>
            {g.spottingType && (
              <Kv label={t.fields.spottingType}>
                {de.pages.gerbils.spottingTypes[
                  g.spottingType as keyof typeof de.pages.gerbils.spottingTypes
                ] || g.spottingType}
              </Kv>
            )}
            {showEnclosure && (
              <Kv label={t.fields.enclosure}>{lookup(enclosureName, g.enclosureId)}</Kv>
            )}
            <Kv label={t.fields.litter}>
              {g.litterId && litterName.has(g.litterId) ? (
                <Link to={`/wuerfe/${g.litterId}`}>{litterName.get(g.litterId)}</Link>
              ) : (
                lookup(litterName, g.litterId)
              )}
            </Kv>
            {ownLitter && (
              <>
                <Kv label={t.detail.parentLittersRoleVater}>{parentLink(fatherId, father.data)}</Kv>
                <Kv label={t.detail.parentLittersRoleMutter}>{parentLink(motherId, mother.data)}</Kv>
              </>
            )}
            <Kv label={t.fields.origin}>
              {g.originContactId && contactName.has(g.originContactId) ? (
                <Link to={`/kontakte/${g.originContactId}`}>{contactName.get(g.originContactId)}</Link>
              ) : (
                g.originBreeder || '—'
              )}
            </Kv>
            {g.status !== 'Deceased' && (
              <Kv label={t.fields.receiver}>{lookup(contactName, g.receiverContactId)}</Kv>
            )}
            <Kv label={t.fields.notes}>{g.notes || '—'}</Kv>
          </dl>
        </section>

        <GerbilAcquisitionSection gerbilId={g.id} />

        <section className="ak-card">
          <h2 className="ak-h2">{t.detail.genetics}</h2>
          {geno ? (
            <dl className="ak-kvlist">
              <Kv label={t.fields.genotype}>
                <code className="ak-genotype">{geno.display}</code>
              </Kv>
              <Kv label={t.detail.resolvedPrefix}>
                {geno.farbschlag}
                {storedColorName &&
                  geno.farbschlag !== de.genetics.unknownFarbschlag &&
                  storedColorName !== geno.farbschlag.replace(' Schecke', '').replace(' Rex', '') && (
                    <small className="ak-mismatch"> ⚠ {t.detail.farbschlagMismatch}</small>
                  )}
              </Kv>
            </dl>
          ) : (
            <p className="ak-empty">{t.detail.genotypeNotSet}</p>
          )}
        </section>

        {/* Externe Vorfahren waren nie im eigenen Bestand → Würfe & Charakter
            sind für sie nicht relevant; statt der Abschnitte ein kurzer Hinweis. */}
        {g.isResident === false && (
          <section className="ak-card">
            <p className="ak-empty">{t.detail.nonResidentNote}</p>
          </section>
        )}

        {g.isResident !== false && (
        <section className="ak-card">
          <button
            type="button"
            className="ak-card-toggle"
            aria-expanded={charExpanded}
            onClick={() => setCharExpanded((v) => !v)}
          >
            <h2 className="ak-h2">{de.character.sectionTitle}</h2>
            <span className="ak-card-chev" aria-hidden="true">
              {charExpanded ? '▴' : '▾'}
            </span>
          </button>
          {charExpanded && (
            <>
              {TRAIT_CATEGORIES.map((cat) => {
                const count = cat.traits.filter((tr) => selectedTraits.has(tr.key)).length
                return (
                  <div className="ak-cgroup" key={cat.category}>
                <div className="ak-glabel">
                  {cat.category}
                  {count > 0 && <span className="ak-gcount">{count}</span>}
                </div>
                <div className="ak-chips">
                  {cat.traits.map((tr) => {
                    const on = selectedTraits.has(tr.key)
                    return (
                      <button
                        key={tr.key}
                        type="button"
                        className={'ak-chip' + (on ? ' on' : '') + (tr.warn ? ' warn' : '')}
                        aria-pressed={on}
                        onClick={() => toggleTrait(tr.key)}
                      >
                        {tr.warn && <span aria-hidden="true">⚠</span>}
                        {tr.label}
                      </button>
                    )
                  })}
                </div>
              </div>
            )
          })}
          <textarea
            className="ak-notes"
            value={charNote}
            placeholder={de.character.notePlaceholder}
            onChange={(e) => setCharNote(e.target.value)}
          />
          <div className="ak-saverow">
            <button
              type="button"
              className="ak-btn primary"
              disabled={saveCharacter.pending}
              onClick={async () => {
                const r = await saveCharacter.run()
                if (r.ok) {
                  toast.success(de.common.saved)
                  gerbil.reload()
                } else {
                  toast.error(r.error)
                }
              }}
            >
              {saveCharacter.pending ? t.form.saving : de.character.save}
            </button>
            {saveCharacter.error && <span className="error-text">{saveCharacter.error}</span>}
              </div>
            </>
          )}
        </section>
        )}

        {g.isResident !== false && (
        <section className="ak-card">
          <h2 className="ak-h2">{t.detail.parentLittersTitle}</h2>
          {parentLitters.loading && <p className="muted">{de.common.loading}</p>}
          {!parentLitters.loading && (parentLitters.data?.items.length ?? 0) === 0 && (
            <p className="ak-empty">{t.detail.parentLittersEmpty}</p>
          )}
          {(parentLitters.data?.items.length ?? 0) > 0 && (
            <ul className="card-list">
              {(parentLitters.data?.items ?? []).map((litter) => (
                <li key={litter.id}>
                  <Link to={`/wuerfe/${litter.id}`} className="gerbil-card">
                    <span className="gerbil-card__name">{litter.name}</span>
                    <span className="badge badge--active">
                      {litter.fatherId === id
                        ? t.detail.parentLittersRoleVater
                        : t.detail.parentLittersRoleMutter}
                    </span>
                    <span className="gerbil-card__meta">{formatDate(litter.date)}</span>
                    {litter.totalBorn !== null && (
                      <span className="gerbil-card__meta">
                        {litter.totalBorn} {de.pages.litters.countLabel}
                      </span>
                    )}
                  </Link>
                </li>
              ))}
            </ul>
          )}
        </section>
        )}

        <section className="ak-card">
          <h2 className="visually-hidden">{t.detail.moreData}</h2>
          <div className="ak-tabs" role="tablist">
            {(['photos', 'health', 'weight'] as const).map((key) => (
              <button
                key={key}
                type="button"
                role="tab"
                aria-selected={tab === key}
                className={tab === key ? 'ak-tab active' : 'ak-tab'}
                onClick={() => setTab(key)}
              >
                {t.detail.tabs[key]}
              </button>
            ))}
          </div>
          <div className="ak-tabpanel" role="tabpanel">
            {tab === 'photos' && <GerbilPhotosTab gerbilId={g.id} />}
            {tab === 'health' && <GerbilHealthTab gerbilId={g.id} />}
            {tab === 'weight' && <GerbilWeightTab gerbilId={g.id} />}
          </div>
        </section>
      </div>

      <ReportErrorDialog
        open={reportOpen}
        onClose={() => setReportOpen(false)}
        context={{ context: 'gerbil-detail', gerbilId: g.id, entityName: g.name || de.pages.gerbils.nameless }}
      />

      <ProvenanceDialog
        open={provenanceOpen}
        onClose={() => setProvenanceOpen(false)}
        provenance={g.provenance}
      />
    </section>
  )
}
