import { ChangeEvent, useEffect, useMemo, useState } from "react";
import { Link, useSearchParams } from "react-router-dom";

import { portalRuntimeConfig } from "../config/runtime";
import {
  FiscalDocumentInboxItemResponse,
  FiscalDocumentInboxListResponse,
  FiscalDocumentInboxStatusResponse,
  FiscalDocumentRead,
  FiscalDocumentSettingsResponse,
  FiscalDocumentsListResponse,
  downloadFiscalDocument,
  fetchFiscalDocumentInbox,
  fetchFiscalDocumentSettings,
  fetchFiscalDocumentInboxStatus,
  fetchFiscalDocuments,
  syncFiscalDocumentInbox,
  startGoogleWorkspaceAuthorization,
  updateFiscalDocumentSettings,
  uploadFiscalDocuments
} from "../lib/api";

type FiscalFilter = "all" | "invoice" | "delivery_note" | "to_review";

function formatFiscalType(type: FiscalDocumentRead["document_type"]) {
  if (type === "invoice") {
    return "Fattura";
  }
  if (type === "delivery_note") {
    return "Bolla / DDT";
  }
  return "Da classificare";
}

function formatAmount(value: number | null | undefined, currency: string) {
  if (value === null || value === undefined) {
    return "Non rilevato";
  }
  return new Intl.NumberFormat("it-IT", {
    style: "currency",
    currency: currency || "EUR"
  }).format(value);
}

function formatDocumentDate(value: string | null | undefined) {
  if (!value) {
    return "Data non rilevata";
  }
  const parsed = new Date(`${value}T00:00:00`);
  if (Number.isNaN(parsed.getTime())) {
    return value;
  }
  return parsed.toLocaleDateString("it-IT");
}

function buildGoogleFlashMessage(searchParams: URLSearchParams): string | null {
  const google = searchParams.get("google");
  const detail = searchParams.get("detail");

  if (google === "connected") {
    return "Account Google collegato. La mailbox fornitori puo ora essere usata per i documenti fiscali in arrivo.";
  }

  if (google === "error") {
    return detail ? `Autorizzazione Google non completata: ${detail}` : "Autorizzazione Google non completata.";
  }

  return null;
}

export function FiscalDocumentsPage() {
  const [searchParams, setSearchParams] = useSearchParams();
  const [documents, setDocuments] = useState<FiscalDocumentRead[]>([]);
  const [inboxItems, setInboxItems] = useState<FiscalDocumentInboxItemResponse[]>([]);
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [filter, setFilter] = useState<FiscalFilter>("all");
  const [busy, setBusy] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [mailboxEmail, setMailboxEmail] = useState("");
  const [mailboxUpdatedAt, setMailboxUpdatedAt] = useState<string | null>(null);
  const [savingMailbox, setSavingMailbox] = useState(false);
  const [inboxStatus, setInboxStatus] = useState<FiscalDocumentInboxStatusResponse | null>(null);
  const [connectingInbox, setConnectingInbox] = useState(false);
  const [syncingInbox, setSyncingInbox] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [flash, setFlash] = useState<string | null>(null);

  useEffect(() => {
    async function loadDocuments() {
      setBusy(true);
      try {
        const [documentsResponse, settingsResponse, inboxResponse, inboxItemsResponse]: [
          FiscalDocumentsListResponse,
          FiscalDocumentSettingsResponse,
          FiscalDocumentInboxStatusResponse,
          FiscalDocumentInboxListResponse
        ] = await Promise.all([
          fetchFiscalDocuments(portalRuntimeConfig.apiHubBaseUrl),
          fetchFiscalDocumentSettings(portalRuntimeConfig.apiHubBaseUrl),
          fetchFiscalDocumentInboxStatus(portalRuntimeConfig.apiHubBaseUrl),
          fetchFiscalDocumentInbox(portalRuntimeConfig.apiHubBaseUrl)
        ]);
        setDocuments(documentsResponse.items);
        setSelectedId((current) => current ?? documentsResponse.items[0]?.id ?? null);
        setMailboxEmail(settingsResponse.inbound_email ?? "");
        setMailboxUpdatedAt(settingsResponse.updated_at ?? null);
        setInboxStatus(inboxResponse);
        setInboxItems(inboxItemsResponse.items);
        setError(null);
      } catch (loadError) {
        setError(loadError instanceof Error ? loadError.message : "Archivio fiscale non disponibile.");
      } finally {
        setBusy(false);
      }
    }

    void loadDocuments();
  }, []);

  useEffect(() => {
    const message = buildGoogleFlashMessage(searchParams);
    if (!message) {
      return;
    }

    setFlash(message);
    setSearchParams({}, { replace: true });
  }, [searchParams, setSearchParams]);

  const filteredDocuments = useMemo(() => {
    if (filter === "all") {
      return documents;
    }
    if (filter === "to_review") {
      return documents.filter((item) => item.review_status === "to_review");
    }
    return documents.filter((item) => item.document_type === filter);
  }, [documents, filter]);

  const selectedDocument =
    filteredDocuments.find((item) => item.id === selectedId) ??
    documents.find((item) => item.id === selectedId) ??
    filteredDocuments[0] ??
    null;

  async function handleUpload(event: ChangeEvent<HTMLInputElement>) {
    const files = Array.from(event.target.files ?? []);
    if (files.length === 0) {
      return;
    }

    setUploading(true);
    setError(null);
    setFlash(null);
    try {
      const response: FiscalDocumentsListResponse = await uploadFiscalDocuments(portalRuntimeConfig.apiHubBaseUrl, files);
      setDocuments(response.items);
      setSelectedId(response.items[0]?.id ?? null);
      setFlash(`${files.length} documento fiscale caricato nell'archivio del locale.`);
    } catch (uploadError) {
      setError(uploadError instanceof Error ? uploadError.message : "Caricamento documenti fiscali fallito.");
    } finally {
      event.target.value = "";
      setUploading(false);
    }
  }

  async function handleDownload(document: FiscalDocumentRead) {
    try {
      const blob = await downloadFiscalDocument(portalRuntimeConfig.apiHubBaseUrl, document.id);
      const url = URL.createObjectURL(blob);
      const anchor = window.document.createElement("a");
      anchor.href = url;
      anchor.download = document.display_name;
      anchor.click();
      URL.revokeObjectURL(url);
    } catch (downloadError) {
      setError(downloadError instanceof Error ? downloadError.message : "Download documento fiscale non riuscito.");
    }
  }

  async function handleMailboxSave(nextEmail?: string) {
    const effectiveEmail = nextEmail ?? mailboxEmail;
    setSavingMailbox(true);
    setError(null);
    setFlash(null);
    try {
      const response = await updateFiscalDocumentSettings(portalRuntimeConfig.apiHubBaseUrl, {
        inbound_email: effectiveEmail.trim() || null
      });
      const inboxResponse = await fetchFiscalDocumentInboxStatus(portalRuntimeConfig.apiHubBaseUrl);
      setMailboxEmail(response.inbound_email ?? "");
      setMailboxUpdatedAt(response.updated_at ?? null);
      setInboxStatus(inboxResponse);
      if (
        response.inbound_email &&
        inboxResponse.google_configured &&
        (!inboxResponse.google_connected || !inboxResponse.gmail_scope_granted || !inboxResponse.mailbox_matches_google_account)
      ) {
        setFlash("Mailbox salvata. Ti porto ora nell'autorizzazione Google per collegare questa casella.");
        await handleConnectInbox();
        return;
      }

      setFlash(
        response.inbound_email
          ? "Mailbox documenti fiscali salvata. La useremo per l'ingestione automatica delle mail fornitori."
          : "Mailbox documenti fiscali rimossa dal locale."
      );
    } catch (saveError) {
      setError(saveError instanceof Error ? saveError.message : "Salvataggio mailbox non riuscito.");
    } finally {
      setSavingMailbox(false);
    }
  }

  async function handleConnectInbox() {
    setConnectingInbox(true);
    setError(null);
    try {
      const response = await startGoogleWorkspaceAuthorization(
        portalRuntimeConfig.apiHubBaseUrl,
        "/fiscal-documents",
        "fiscal-documents"
      );
      window.location.assign(response.authorization_url);
    } catch (connectError) {
      setError(connectError instanceof Error ? connectError.message : "Avvio collegamento Google non riuscito.");
      setConnectingInbox(false);
    }
  }

  async function handleSyncInbox() {
    setSyncingInbox(true);
    setError(null);
    setFlash(null);
    try {
      const [inboxResponse, documentsResponse, inboxStatusResponse]: [
        FiscalDocumentInboxListResponse,
        FiscalDocumentsListResponse,
        FiscalDocumentInboxStatusResponse
      ] = await Promise.all([
        syncFiscalDocumentInbox(portalRuntimeConfig.apiHubBaseUrl),
        fetchFiscalDocuments(portalRuntimeConfig.apiHubBaseUrl),
        fetchFiscalDocumentInboxStatus(portalRuntimeConfig.apiHubBaseUrl)
      ]);
      setInboxItems(inboxResponse.items);
      setDocuments(documentsResponse.items);
      setSelectedId((current) => current ?? documentsResponse.items[0]?.id ?? null);
      setInboxStatus(inboxStatusResponse);
      if (inboxResponse.total_count === 0) {
        setFlash("Nessun allegato fiscale rilevato nella mailbox in questo momento.");
      } else {
        setFlash(
          `Inbox sincronizzata: ${inboxResponse.imported_count} allegati importati, ${inboxResponse.unsupported_count} non supportati, ${inboxResponse.error_count} con errore.`
        );
      }
    } catch (syncError) {
      setError(syncError instanceof Error ? syncError.message : "Sincronizzazione inbox non riuscita.");
    } finally {
      setSyncingInbox(false);
    }
  }

  return (
    <section className="stack-lg fiscal-documents-shell">
      <section className="panel fiscal-documents-hero">
        <div className="panel-heading">
          <div>
            <p className="eyebrow">Strumenti</p>
            <h2 className="page-title">Documenti fiscali</h2>
            <p className="muted-copy">
              Carica fatture e bolle del locale, archiviali per fornitore e prepara la base per il confronto con ordini e pagamenti.
            </p>
          </div>
          <div className="fiscal-documents-actions">
            <label className="button-primary fiscal-upload-button">
              {uploading ? "Caricamento..." : "Carica documenti fiscali"}
              <input type="file" accept=".pdf,.png,.jpg,.jpeg,.txt,.md,.csv" multiple onChange={handleUpload} hidden />
            </label>
            <Link to="/dashboard" className="button-secondary">
              Torna a Strumenti
            </Link>
          </div>
        </div>

        <div className="stats-grid fiscal-documents-stats">
          <article className="stat-card">
            <span>Totale documenti</span>
            <strong>{documents.length}</strong>
            <small>Archivio fiscale del locale</small>
          </article>
          <article className="stat-card">
            <span>Fatture</span>
            <strong>{documents.filter((item) => item.document_type === "invoice").length}</strong>
            <small>Documenti classificati come fattura</small>
          </article>
          <article className="stat-card">
            <span>Bolle</span>
            <strong>{documents.filter((item) => item.document_type === "delivery_note").length}</strong>
            <small>Documenti classificati come bolla o DDT</small>
          </article>
          <article className="stat-card">
            <span>Da verificare</span>
            <strong>{documents.filter((item) => item.review_status === "to_review").length}</strong>
            <small>Pronti per review manuale dell'admin</small>
          </article>
        </div>
      </section>

      <section className="panel fiscal-mailbox-card stack-md">
        <div className="panel-heading">
          <div>
            <p className="eyebrow">Mailbox fornitori</p>
            <h3>Casella di ricezione documenti</h3>
            <p className="muted-copy">
              Inserisci l'indirizzo email a cui i fornitori inviano bolle e fatture. In questo step la salviamo per il locale,
              nel prossimo la useremo per l'ingestione automatica dei documenti in arrivo.
            </p>
          </div>
        </div>

        <div className="fiscal-mailbox-form">
          <label className="field">
            <span>Email dedicata a bolle e fatture</span>
            <input
              type="email"
              value={mailboxEmail}
              onChange={(event) => setMailboxEmail(event.target.value)}
              placeholder="documenti@tuolocale.it"
              autoComplete="email"
            />
          </label>

          <div className="fiscal-mailbox-inline">
            <button type="button" className="button-primary" onClick={() => void handleMailboxSave()} disabled={savingMailbox}>
              {savingMailbox ? "Salvataggio..." : "Salva mailbox"}
            </button>
            <button
              type="button"
              className="button-secondary"
              onClick={() => {
                setMailboxEmail("");
                void handleMailboxSave("");
              }}
              disabled={savingMailbox || !mailboxEmail.trim()}
            >
              Rimuovi mailbox
            </button>
          </div>

          <p className="muted-copy">
            {mailboxUpdatedAt
              ? `Ultimo aggiornamento: ${new Date(mailboxUpdatedAt).toLocaleString("it-IT")}`
              : "Nessuna mailbox configurata per questo locale."}
          </p>
        </div>
      </section>

      <section className="panel fiscal-inbox-card stack-md">
        <div className="panel-heading">
          <div>
            <p className="eyebrow">In arrivo</p>
            <h3>Stato lettura mailbox</h3>
            <p className="muted-copy">
              Questa sezione prepara l'ingestione automatica delle email dei fornitori usando la connessione Google del locale.
            </p>
          </div>
          <div className="fiscal-documents-actions">
            <button
              type="button"
              className="button-secondary"
              onClick={() => void handleConnectInbox()}
              disabled={connectingInbox}
            >
              {connectingInbox ? "Apertura..." : "Collega / ricollega Google"}
            </button>
            <button
              type="button"
              className="button-primary"
              onClick={() => void handleSyncInbox()}
              disabled={syncingInbox || !inboxStatus?.ready_for_sync}
            >
              {syncingInbox ? "Sincronizzazione..." : "Sincronizza inbox"}
            </button>
          </div>
        </div>

        {inboxStatus ? (
          <>
            <div className="fiscal-detail-grid">
              <article className="stat-card">
                <span>Mailbox locale</span>
                <strong>{inboxStatus.inbound_email || "Non configurata"}</strong>
                <small>{inboxStatus.mailbox_configured ? "Casella salvata per il locale" : "Inserisci prima la mailbox fornitori"}</small>
              </article>
              <article className="stat-card">
                <span>Account Google</span>
                <strong>{inboxStatus.google_account_email || "Non collegato"}</strong>
                <small>{inboxStatus.google_connected ? "Connessione Google presente" : "Serve il collegamento Google del locale"}</small>
              </article>
              <article className="stat-card">
                <span>Permesso Gmail</span>
                <strong>{inboxStatus.gmail_scope_granted ? "Attivo" : "Da autorizzare"}</strong>
                <small>Serve Gmail in sola lettura per leggere le email in arrivo.</small>
              </article>
              <article className="stat-card">
                <span>Sync inbox</span>
                <strong>{inboxStatus.ready_for_sync ? "Pronta" : "Non pronta"}</strong>
                <small>{inboxStatus.mailbox_matches_google_account ? "Mailbox e account coincidono" : "Mailbox e account devono coincidere"}</small>
              </article>
            </div>

            <div className="empty-state">
              <strong>Prossimo passo</strong>
              <p>{inboxStatus.next_step}</p>
            </div>

            <div className="fiscal-document-list">
              {inboxItems.length === 0 ? (
                <div className="empty-state">
                  <strong>Nessun allegato sincronizzato.</strong>
                  <p>Quando esegui la sync, qui compariranno gli allegati email importati dalla mailbox fornitori.</p>
                </div>
              ) : (
                inboxItems.map((item) => (
                  <button
                    key={item.id}
                    type="button"
                    className="fiscal-document-item"
                    onClick={() => {
                      if (item.document_id) {
                        setSelectedId(item.document_id);
                      }
                    }}
                    disabled={!item.document_id}
                  >
                    <div className="fiscal-document-item-head">
                      <strong>{item.attachment_name}</strong>
                      <span className={`status-chip is-${item.sync_status}`}>{item.sync_status}</span>
                    </div>
                    <p>
                      {item.subject || "Email senza oggetto"}
                      {item.sender ? ` · ${item.sender}` : ""}
                    </p>
                    <p>
                      {item.received_at ? new Date(item.received_at).toLocaleString("it-IT") : "Data email non disponibile"}
                      {item.error_detail ? ` · ${item.error_detail}` : ""}
                    </p>
                  </button>
                ))
              )}
            </div>
          </>
        ) : (
          <div className="empty-state">
            <strong>Stato inbox non ancora disponibile.</strong>
            <p>Ricarica la pagina o salva la mailbox del locale per iniziare la configurazione.</p>
          </div>
        )}
      </section>

      {flash ? <section className="panel success-banner">{flash}</section> : null}
      {error ? <section className="panel inline-error-banner">{error}</section> : null}

      <section className="fiscal-documents-workspace">
        <section className="panel stack-md">
          <div className="panel-heading">
            <div>
              <p className="eyebrow">Archivio</p>
              <h3>Documenti ricevuti</h3>
            </div>
            <div className="fiscal-filter-row" role="tablist" aria-label="Filtro documenti fiscali">
              {[
                ["all", "Tutti"],
                ["invoice", "Fatture"],
                ["delivery_note", "Bolle"],
                ["to_review", "Da verificare"]
              ].map(([value, label]) => (
                <button
                  key={value}
                  type="button"
                  className={`button-secondary fiscal-filter-chip${filter === value ? " is-active" : ""}`}
                  onClick={() => setFilter(value as FiscalFilter)}
                >
                  {label}
                </button>
              ))}
            </div>
          </div>

          <div className="fiscal-document-list">
            {busy ? <p className="muted-copy">Carico l'archivio fiscale del locale...</p> : null}
            {!busy && filteredDocuments.length === 0 ? (
              <div className="empty-state">
                <strong>Nessun documento fiscale in questa vista.</strong>
                <p>Carica una fattura o una bolla per iniziare a popolare l'archivio.</p>
              </div>
            ) : null}

            {filteredDocuments.map((document) => (
              <button
                key={document.id}
                type="button"
                className={`fiscal-document-item${selectedDocument?.id === document.id ? " is-active" : ""}`}
                onClick={() => setSelectedId(document.id)}
              >
                <div className="fiscal-document-item-head">
                  <strong>{document.display_name}</strong>
                  <span className={`status-chip is-${document.document_type}`}>{formatFiscalType(document.document_type)}</span>
                </div>
                <p>{document.summary_text || "Documento caricato, in attesa di verifica."}</p>
              </button>
            ))}
          </div>
        </section>

        <section className="panel stack-md fiscal-document-detail">
          <div className="panel-heading">
            <div>
              <p className="eyebrow">Dettaglio</p>
              <h3>{selectedDocument?.display_name ?? "Seleziona un documento"}</h3>
            </div>
            {selectedDocument ? (
              <button type="button" className="button-secondary" onClick={() => void handleDownload(selectedDocument)}>
                Scarica originale
              </button>
            ) : null}
          </div>

          {selectedDocument ? (
            <>
              <div className="fiscal-detail-grid">
                <article className="stat-card">
                  <span>Tipo</span>
                  <strong>{formatFiscalType(selectedDocument.document_type)}</strong>
                  <small>{selectedDocument.status === "ready" ? "Classificazione iniziale pronta" : "Documento ancora in elaborazione"}</small>
                </article>
                <article className="stat-card">
                  <span>Numero</span>
                  <strong>{selectedDocument.document_number || "Non rilevato"}</strong>
                  <small>{formatDocumentDate(selectedDocument.document_date)}</small>
                </article>
                <article className="stat-card">
                  <span>Emittente</span>
                  <strong>{selectedDocument.supplier_name || "Non rilevato"}</strong>
                  <small>{formatAmount(selectedDocument.total_amount, selectedDocument.currency)}</small>
                </article>
                <article className="stat-card">
                  <span>Verifica</span>
                  <strong>{selectedDocument.review_status === "to_review" ? "Da verificare" : "Verificato"}</strong>
                  <small>{selectedDocument.matching_status === "pending" ? "Matching ordine/bolla/fattura in arrivo" : selectedDocument.matching_status}</small>
                </article>
              </div>

              <section className="panel fiscal-next-steps">
                <div className="panel-heading">
                  <div>
                    <p className="eyebrow">Prossimi step</p>
                    <h3>Workflow che stiamo preparando</h3>
                  </div>
                </div>
                <div className="fiscal-next-steps-list">
                  <article className="stat-card">
                    <span>Bolla vs ordine</span>
                    <strong>In arrivo</strong>
                    <small>Confronteremo righe e quantità con l'ordine confermato per proporre eventuali storni merce.</small>
                  </article>
                  <article className="stat-card">
                    <span>Fattura vs bolle</span>
                    <strong>In arrivo</strong>
                    <small>Confronteremo importi e riferimenti per verificare che il pagamento sia corretto.</small>
                  </article>
                </div>
              </section>

              <section className="panel fiscal-text-preview">
                <div className="panel-heading">
                  <div>
                    <p className="eyebrow">Testo estratto</p>
                    <h3>Base dati del documento</h3>
                  </div>
                </div>
                <pre>{selectedDocument.extracted_text || "Nessun testo leggibile estratto dal documento."}</pre>
              </section>
            </>
          ) : (
            <div className="empty-state">
              <strong>Nessun documento selezionato.</strong>
              <p>Carica o seleziona un documento fiscale per vedere i dati rilevati.</p>
            </div>
          )}
        </section>
      </section>
    </section>
  );
}
