/**
 * RÜCKNAHMEN: Verwaltungsseite für zurückgekommene/zurückgenommene Tiere (/ruecknahmen).
 * Liste + Inline-Formular zum Erfassen/Bearbeiten. Tier-/Kontakt-Bezüge als Links.
 */
import { useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import { de } from '../strings/de'
import {
  createReturn,
  deleteReturn,
  listReturns,
  updateReturn,
  type ReturnRecord,
  type ReturnRecordInput,
} from '../api/returns'
import { listGerbils } from '../api/gerbils'
import { listContactsPaged } from '../api/contacts'
import { useApi, useMutation } from '../hooks/useApi'
import { formatDate } from '../format/labels'

const EMPTY_FORM = {
  gerbilId: '',
  gerbilName: '',
  returnDate: '',
  returnPrice: '',
  originalPrice: '',
  originalSaleDate: '',
  fromContactId: '',
  fromContactName: '',
  note: '',
}
type FormState = typeof EMPTY_FORM

function toInput(form: FormState): ReturnRecordInput {
  const num = (s: string) => (s.trim() === '' ? null : Number(s))
  return {
    gerbilId: form.gerbilId || null,
    gerbilName: form.gerbilName.trim() || null,
    returnDate: form.returnDate ? `${form.returnDate}T00:00:00Z` : null,
    returnPrice: num(form.returnPrice),
    originalPrice: num(form.originalPrice),
    originalSaleDate: form.originalSaleDate ? `${form.originalSaleDate}T00:00:00Z` : null,
    fromContactId: form.fromContactId || null,
    fromContactName: form.fromContactName.trim() || null,
    note: form.note.trim() || null,
  }
}

/** ISO/Date-Wert → "YYYY-MM-DD" für <input type=date>. */
function isoDateInput(value: string | null): string {
  if (!value) return ''
  return value.slice(0, 10)
}

function fromRecord(r: ReturnRecord): FormState {
  return {
    gerbilId: r.gerbilId ?? '',
    gerbilName: r.gerbilName ?? '',
    returnDate: isoDateInput(r.returnDate),
    returnPrice: r.returnPrice == null ? '' : String(r.returnPrice),
    originalPrice: r.originalPrice == null ? '' : String(r.originalPrice),
    originalSaleDate: isoDateInput(r.originalSaleDate),
    fromContactId: r.fromContactId ?? '',
    fromContactName: r.fromContactName ?? '',
    note: r.note ?? '',
  }
}

function formatPrice(value: number | null): string {
  if (value == null) return '—'
  return `${value.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`
}

export default function RuecknahmenPage() {
  const t = de.pages.ruecknahmen

  const returns = useApi(() => listReturns(), [])
  const gerbils = useApi(
    () => listGerbils({ page: 1, pageSize: 1000, orderBy: 'name' }),
    [],
  )
  const contacts = useApi(
    () => listContactsPaged({ page: 1, pageSize: 1000, orderBy: 'name' }),
    [],
  )

  const gerbilName = useMemo(
    () => new Map((gerbils.data?.items ?? []).map((g) => [g.id, g.name])),
    [gerbils.data],
  )
  const contactName = useMemo(
    () => new Map((contacts.data?.items ?? []).map((c) => [c.id, c.name])),
    [contacts.data],
  )

  const [form, setForm] = useState<FormState>(EMPTY_FORM)
  const [editingId, setEditingId] = useState<string | null>(null)
  const [showForm, setShowForm] = useState(false)
  const [validationError, setValidationError] = useState<string | null>(null)

  const save = useMutation((body: ReturnRecordInput) =>
    editingId ? updateReturn(editingId, body) : createReturn(body),
  )
  const removal = useMutation((id: string) => deleteReturn(id))

  function set<K extends keyof FormState>(key: K, value: string) {
    setForm((f) => ({ ...f, [key]: value }))
  }

  function startNew() {
    setForm(EMPTY_FORM)
    setEditingId(null)
    setValidationError(null)
    setShowForm(true)
  }

  function startEdit(r: ReturnRecord) {
    setForm(fromRecord(r))
    setEditingId(r.id)
    setValidationError(null)
    setShowForm(true)
  }

  function cancelForm() {
    setShowForm(false)
    setEditingId(null)
    setForm(EMPTY_FORM)
    setValidationError(null)
  }

  async function onSubmit(e: React.FormEvent) {
    e.preventDefault()
    setValidationError(null)
    if (!form.gerbilId && !form.gerbilName.trim()) {
      setValidationError(t.validationNoAnimal)
      return
    }
    const result = await save.run(toInput(form))
    if (result.ok) {
      cancelForm()
      returns.reload()
    }
  }

  async function onDelete(id: string) {
    if (!window.confirm(t.confirmDelete)) return
    const result = await removal.run(id)
    if (result.ok) returns.reload()
  }

  if (returns.loading) return <p className="muted">{de.common.loading}</p>
  if (returns.error) {
    return (
      <section className="page">
        <h2>{t.title}</h2>
        <div className="alert alert--error">
          <span>{returns.error}</span>
          <button type="button" className="btn" onClick={returns.reload}>
            {de.common.retry}
          </button>
        </div>
      </section>
    )
  }

  const items = returns.data ?? []

  return (
    <section className="page">
      <header className="page-head">
        <div>
          <h2>{t.title}</h2>
          <p className="muted">{items.length === 0 ? t.subtitle : t.countText(items.length)}</p>
        </div>
        {!showForm && (
          <div className="head-actions">
            <button type="button" className="btn btn--primary" onClick={startNew}>
              {t.newButton}
            </button>
          </div>
        )}
      </header>

      {showForm && (
        <form className="card" onSubmit={onSubmit} style={{ marginBottom: '1rem' }}>
          <h3>{editingId ? t.editTitle : t.formTitle}</h3>

          <label>
            {t.fields.gerbil}
            <select value={form.gerbilId} onChange={(e) => set('gerbilId', e.target.value)}>
              <option value="">{t.gerbilPlaceholder}</option>
              {(gerbils.data?.items ?? []).map((g) => (
                <option key={g.id} value={g.id}>
                  {g.name}
                </option>
              ))}
            </select>
          </label>

          <label>
            {t.fields.gerbilName}
            <input
              type="text"
              value={form.gerbilName}
              onChange={(e) => set('gerbilName', e.target.value)}
            />
            <small className="muted">{t.fields.gerbilNameHint}</small>
          </label>

          <label>
            {t.fields.returnDate}
            <input
              type="date"
              value={form.returnDate}
              onChange={(e) => set('returnDate', e.target.value)}
            />
          </label>

          <label>
            {t.fields.returnPrice}
            <input
              type="number"
              step="0.01"
              min="0"
              value={form.returnPrice}
              onChange={(e) => set('returnPrice', e.target.value)}
            />
          </label>

          <label>
            {t.fields.originalPrice}
            <input
              type="number"
              step="0.01"
              min="0"
              value={form.originalPrice}
              onChange={(e) => set('originalPrice', e.target.value)}
            />
          </label>

          <label>
            {t.fields.originalSaleDate}
            <input
              type="date"
              value={form.originalSaleDate}
              onChange={(e) => set('originalSaleDate', e.target.value)}
            />
          </label>

          <label>
            {t.fields.fromContact}
            <select value={form.fromContactId} onChange={(e) => set('fromContactId', e.target.value)}>
              <option value="">{t.contactPlaceholder}</option>
              {(contacts.data?.items ?? []).map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name}
                </option>
              ))}
            </select>
          </label>

          <label>
            {t.fields.fromContactName}
            <input
              type="text"
              value={form.fromContactName}
              onChange={(e) => set('fromContactName', e.target.value)}
            />
            <small className="muted">{t.fields.fromContactNameHint}</small>
          </label>

          <label>
            {t.fields.note}
            <textarea
              value={form.note}
              placeholder={t.fields.notePlaceholder}
              onChange={(e) => set('note', e.target.value)}
            />
          </label>

          {validationError && <div className="alert alert--error">{validationError}</div>}
          {save.error && <div className="alert alert--error">{t.saveError}</div>}

          <div className="head-actions">
            <button type="submit" className="btn btn--primary" disabled={save.pending}>
              {save.pending ? t.saving : t.save}
            </button>
            <button type="button" className="btn" onClick={cancelForm} disabled={save.pending}>
              {t.cancel}
            </button>
          </div>
        </form>
      )}

      {removal.error && <div className="alert alert--error">{removal.error}</div>}

      {items.length === 0 ? (
        <p className="muted">{t.empty}</p>
      ) : (
        <ul className="card-list">
          {items.map((r) => {
            const displayName = r.gerbilId
              ? (gerbilName.get(r.gerbilId) ?? r.gerbilName ?? t.unknownAnimal)
              : (r.gerbilName ?? t.unknownAnimal)
            const displayContact = r.fromContactId
              ? (contactName.get(r.fromContactId) ?? r.fromContactName)
              : r.fromContactName
            return (
              <li key={r.id} className="gerbil-card">
                <span className="gerbil-card__name">
                  {r.gerbilId ? (
                    <Link to={`/rennmaeuse/${r.gerbilId}`}>{displayName}</Link>
                  ) : (
                    displayName
                  )}
                </span>
                <span className="gerbil-card__meta">
                  {t.returnedOn} {formatDate(isoDateInput(r.returnDate) || null)}
                  {displayContact && (
                    <>
                      {' · '}
                      {t.from}{' '}
                      {r.fromContactId ? (
                        <Link to={`/kontakte/${r.fromContactId}`}>{displayContact}</Link>
                      ) : (
                        displayContact
                      )}
                    </>
                  )}
                  {r.returnPrice != null && <> · {formatPrice(r.returnPrice)}</>}
                  {r.note && <> · {r.note}</>}
                </span>
                <span className="head-actions">
                  <button type="button" className="btn" onClick={() => startEdit(r)}>
                    {t.edit}
                  </button>
                  <button
                    type="button"
                    className="btn btn--danger"
                    onClick={() => onDelete(r.id)}
                    disabled={removal.pending}
                  >
                    {t.delete}
                  </button>
                </span>
              </li>
            )
          })}
        </ul>
      )}
    </section>
  )
}
