/**
 * INBOX-1: Anfrage-Detail — Nachricht lesen, Triage (Status / Verwerfen /
 * Abnehmer zuordnen), KI-Antwortentwurf (INBOX-2) und Versand (INBOX-3).
 *
 * - Triage-PUT überschreibt assignedContactId immer → bei jedem Update wird
 *   die aktuelle Zuordnung mitgesendet (Backend-Vertrag, siehe api/requests.ts).
 * - KI entwirft NUR (human-in-the-loop): Entwurf landet editierbar im
 *   Textfeld; gesendet wird ausschließlich nach Bestätigung.
 * - 503 AiKeyMissing / MailNotConfigured / MailAuthFailed → deutsche Hinweise
 *   (gleiches Muster wie die Verkaufstext-KI).
 */
import { useState } from 'react'
import { Link, useParams } from 'react-router-dom'
import { de } from '../strings/de'
import { errorCode } from '../api/client'
import {
  REQUEST_STATUSES,
  draftReply,
  getRequest,
  problemTitle,
  sendReply,
  triageRequest,
  type InboxRequest,
  type RequestStatus,
} from '../api/requests'
import { listContactsPaged } from '../api/contacts'
import { useApi, useMutation } from '../hooks/useApi'
import { StatusBadge } from './AnfragenPage'
import { formatDateTime } from '../format/labels'
import './anfragen.css'

export default function AnfrageDetailPage() {
  const t = de.pages.anfragen
  const td = t.detail
  const { id = '' } = useParams()

  const request = useApi(() => getRequest(id), [id])
  const contacts = useApi(() => listContactsPaged({ page: 1, pageSize: 1000, orderBy: 'name' }), [])

  // Antwort-Text: lokaler Entwurf; aus draftReply vorbefüllt, sobald geladen.
  const [reply, setReply] = useState('')
  const [replyInitFor, setReplyInitFor] = useState<string | null>(null)
  if (request.data && replyInitFor !== request.data.id) {
    setReplyInitFor(request.data.id)
    setReply(request.data.draftReply ?? '')
  }

  const [notice, setNotice] = useState<string | null>(null)
  const [hint, setHint] = useState<string | null>(null)

  /** Aktuellen Server-Stand nach einer Mutation übernehmen (ohne Neu-Laden). */
  const [override, setOverride] = useState<InboxRequest | null>(null)
  const current = override && override.id === id ? override : request.data

  const triage = useMutation((next: { status?: RequestStatus; assignedContactId: string | null }) =>
    triageRequest(id, next),
  )
  async function applyTriage(next: { status?: RequestStatus; assignedContactId: string | null }) {
    setNotice(null)
    const result = await triage.run(next)
    if (result.ok && current) {
      setOverride({
        ...current,
        status: next.status ?? current.status,
        assignedContactId: next.assignedContactId,
      })
    }
  }

  const draft = useMutation(() => draftReply(id))
  async function onDraft() {
    setHint(null)
    setNotice(null)
    const result = await draft.run()
    if (result.ok) {
      setOverride(result.value)
      setReply(result.value.draftReply ?? '')
      return
    }
    const code = errorCode(result.cause)
    if (code === 'AiKeyMissing') setHint(td.aiKeyMissing)
    else if (code === 'AiUpstreamError') setHint(td.aiUpstreamError)
    // sonst: draft.error treibt den Alert
  }

  const send = useMutation(() => sendReply(id, reply))
  async function onSend() {
    setHint(null)
    setNotice(null)
    if (reply.trim() === '') {
      setHint(td.sendEmptyBody)
      return
    }
    if (!window.confirm(td.sendConfirm)) return
    const result = await send.run()
    if (result.ok) {
      setOverride(result.value)
      setNotice(td.sent)
      return
    }
    const title = problemTitle(result.cause)
    if (title === 'MailNotConfigured') setHint(t.mailNotConfigured)
    else if (title === 'MailAuthFailed') setHint(t.mailAuthFailed)
  }

  if (request.loading) return <p className="muted">{de.common.loading}</p>
  if (request.error || !current) {
    return (
      <section className="page">
        <p className="muted">{request.error ?? td.notFound}</p>
        <Link to="/anfragen" className="btn">
          {td.back}
        </Link>
      </section>
    )
  }

  const r = current
  const contactItems = contacts.data?.items ?? []
  const mutationError = triage.error ?? draft.error ?? send.error

  return (
    <section className="page anfrage-detail">
      <header className="page-head">
        <div>
          <h2>{r.subject ?? td.noSubject}</h2>
          <StatusBadge status={r.status} />
        </div>
        <div className="head-actions">
          <Link to="/anfragen" className="btn">
            {td.back}
          </Link>
        </div>
      </header>

      <dl className="def-list">
        <div className="def-row">
          <dt>{td.from}</dt>
          <dd>{r.fromName ? `${r.fromName} <${r.fromAddress}>` : r.fromAddress}</dd>
        </div>
        <div className="def-row">
          <dt>{td.receivedAt}</dt>
          <dd>{formatDateTime(r.receivedAt)}</dd>
        </div>
        {r.answeredAt && (
          <div className="def-row">
            <dt>{td.answeredAt}</dt>
            <dd>{formatDateTime(r.answeredAt)}</dd>
          </div>
        )}
      </dl>

      <h3>{td.message}</h3>
      <div className="anfrage-body">{r.bodyText?.trim() ? r.bodyText : td.noBody}</div>

      <h3>{td.triage}</h3>
      {mutationError && <div className="alert alert--error">{mutationError}</div>}
      <div className="anfrage-triage">
        <label className="field">
          <span>{td.statusLabel}</span>
          <select
            value={r.status}
            disabled={triage.pending}
            onChange={(e) =>
              applyTriage({
                status: e.target.value as RequestStatus,
                assignedContactId: r.assignedContactId,
              })
            }
          >
            {REQUEST_STATUSES.map((s) => (
              <option key={s} value={s}>
                {t.statusLabels[s]}
              </option>
            ))}
          </select>
        </label>

        <label className="field">
          <span>{td.assignContact}</span>
          <select
            value={r.assignedContactId ?? ''}
            disabled={triage.pending || contacts.loading}
            onChange={(e) => {
              const contactId = e.target.value || null
              // Zuordnung setzt den Status auf „Zugeordnet“ (Beantwortet bleibt).
              applyTriage({
                status:
                  contactId && r.status !== 'Answered' ? 'Assigned' : undefined,
                assignedContactId: contactId,
              })
            }}
          >
            <option value="">{td.assignNone}</option>
            {contactItems.map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
          </select>
        </label>

        {r.status !== 'Abandoned' && (
          <button
            type="button"
            className="btn btn--danger anfrage-abandon"
            disabled={triage.pending}
            onClick={() => {
              if (!window.confirm(td.abandonConfirm)) return
              applyTriage({ status: 'Abandoned', assignedContactId: r.assignedContactId })
            }}
          >
            {td.abandon}
          </button>
        )}
      </div>

      <h3>{td.reply}</h3>
      {notice && <div className="alert">{notice}</div>}
      {hint && <div className="alert">{hint}</div>}
      <div className="form anfrage-reply">
        <textarea
          className="anfrage-reply__text"
          placeholder={td.replyPlaceholder}
          value={reply}
          onChange={(e) => setReply(e.target.value)}
        />
        <p className="muted anfrage-reply__hint">{td.draftHint}</p>
        <div className="form-actions">
          <button type="button" className="btn" onClick={onDraft} disabled={draft.pending}>
            {draft.pending ? td.drafting : td.draftButton}
          </button>
          <button
            type="button"
            className="btn btn--primary"
            onClick={onSend}
            disabled={send.pending}
          >
            {send.pending ? td.sending : td.send}
          </button>
        </div>
      </div>
    </section>
  )
}
