import {
  type Component,
  createSignal,
  onMount,
  Show,
  For,
} from 'solid-js';
import { useParams, useNavigate, A } from '@solidjs/router';
import { ArrowLeft, ExternalLink, Trash2, AlertTriangle, Mail, Send, FileDown } from 'lucide-solid';
import { useI18n } from '~/i18n';
import { useAuth } from '~/contexts/AuthContext';
import { synthesesApi } from '~/api/syntheses';
import { articleHistoryApi } from '~/api/articleHistory';
import { isApiError } from '~/types';
import type { Synthesis, NewsItem as NewsItemType, ArticleHistoryEntry } from '~/types';
import { extractWeekNumber, formatDateLong } from '~/utils/dates';
import LoadingSpinner from '~/components/ui/LoadingSpinner';

/** Renders a single news article with its title (linked) and summary. */
const NewsItemCard: Component<{ item: NewsItemType }> = (props) => {
  return (
    <div class="bg-white rounded-lg shadow-sm border border-gray-100 p-6 hover:shadow-md transition-shadow">
      <h3 class="text-lg font-semibold text-indigo-700 mb-2">
        <a
          href={props.item.url}
          target="_blank"
          rel="noopener noreferrer"
          class="hover:underline flex items-center gap-2"
        >
          {props.item.title}
          <ExternalLink class="h-4 w-4 text-gray-400 flex-shrink-0" />
        </a>
      </h3>
      <p class="text-gray-700 leading-relaxed text-sm">
        {props.item.summary}
      </p>
    </div>
  );
};

/** Renders a titled category section containing a list of {@link NewsItemCard}s. */
const Section: Component<{ title: string; items: NewsItemType[] }> = (props) => {
  return (
    <Show when={props.items && props.items.length > 0}>
      <div class="mb-10">
        <h2 class="text-2xl font-bold text-gray-900 mb-6 border-b pb-2">
          {props.title}
        </h2>
        <div class="space-y-6">
          <For each={props.items}>
            {(item) => <NewsItemCard item={item} />}
          </For>
        </div>
      </div>
    </Show>
  );
};

/**
 * Detail view for a single synthesis, with email send and export capabilities.
 *
 * - **Email send flow**: The email input is pre-filled from the authenticated
 *   user's address. On send, a POST is made to the backend; a success banner
 *   auto-dismisses after 5 seconds.
 * - **Export download**: Markdown and PDF exports call {@link fetchFile} to
 *   obtain a binary Response, then {@link triggerDownload} to create a
 *   temporary `<a>` element that triggers the browser download dialog.
 */
const SynthesisDetail: Component = () => {
  const { t } = useI18n();
  const { user } = useAuth();
  const params = useParams<{ id: string }>();
  const navigate = useNavigate();

  const [synthesis, setSynthesis] = createSignal<Synthesis | null>(null);
  const [loading, setLoading] = createSignal(true);
  const [error, setError] = createSignal<string | null>(null);
  const [showDeleteConfirm, setShowDeleteConfirm] = createSignal(false);
  const [isDeleting, setIsDeleting] = createSignal(false);

  // Email state
  const [email, setEmail] = createSignal('');
  const [sendingEmail, setSendingEmail] = createSignal(false);
  const [emailSuccess, setEmailSuccess] = createSignal(false);
  const [emailError, setEmailError] = createSignal<string | null>(null);

  // Export state
  const [exportingMarkdown, setExportingMarkdown] = createSignal(false);
  const [exportingPdf, setExportingPdf] = createSignal(false);
  const [exportError, setExportError] = createSignal<string | null>(null);

  // Provenance state
  const [provenance, setProvenance] = createSignal<ArticleHistoryEntry[]>([]);
  const [showProvenance, setShowProvenance] = createSignal(false);
  const [provenanceLoading, setProvenanceLoading] = createSignal(false);

  onMount(async () => {
    // Pre-fill email from authenticated user
    const currentUser = user();
    if (currentUser?.email) {
      setEmail(currentUser.email);
    }

    try {
      const data = await synthesesApi.get(params.id);
      setSynthesis(data);
    } catch (err) {
      if (isApiError(err) && err.status === 404) {
        setError(t('synthesis.notFound'));
      } else if (isApiError(err)) {
        setError(err.message);
      } else {
        setError(t('synthesis.loadError'));
      }
    } finally {
      setLoading(false);
    }
  });

  const handleDelete = async () => {
    const synth = synthesis();
    if (!synth) return;

    setIsDeleting(true);
    try {
      await synthesesApi.remove(synth.id);
      navigate('/');
    } catch (err) {
      if (isApiError(err)) {
        setError(err.message);
      } else {
        setError(t('synthesis.deleteError'));
      }
      setIsDeleting(false);
      setShowDeleteConfirm(false);
    }
  };

  const handleSendEmail = async () => {
    const synth = synthesis();
    if (!synth || !email()) return;

    setSendingEmail(true);
    setEmailError(null);
    setEmailSuccess(false);

    try {
      await synthesesApi.sendEmail(synth.id, email());
      setEmailSuccess(true);
      setTimeout(() => setEmailSuccess(false), 5000);
    } catch (err) {
      if (isApiError(err)) {
        setEmailError(err.message);
      } else {
        setEmailError(t('synthesis.email.error'));
      }
    } finally {
      setSendingEmail(false);
    }
  };

  const handleExportMarkdown = async () => {
    const synth = synthesis();
    if (!synth) return;

    setExportingMarkdown(true);
    setExportError(null);

    try {
      await synthesesApi.exportMarkdown(synth.id);
    } catch (err) {
      if (isApiError(err)) {
        setExportError(err.message);
      } else {
        setExportError(t('synthesis.export.error'));
      }
    } finally {
      setExportingMarkdown(false);
    }
  };

  const handleExportPdf = async () => {
    const synth = synthesis();
    if (!synth) return;

    setExportingPdf(true);
    setExportError(null);

    try {
      await synthesesApi.exportPdf(synth.id);
    } catch (err) {
      if (isApiError(err)) {
        setExportError(err.message);
      } else {
        setExportError(t('synthesis.export.error'));
      }
    } finally {
      setExportingPdf(false);
    }
  };

  const loadProvenance = async () => {
    if (provenance().length > 0) return; // Already loaded
    setProvenanceLoading(true);
    try {
      const data = await articleHistoryApi.getProvenance(params.id);
      setProvenance(data);
    } catch {
      // Provenance may not be available for old syntheses
    } finally {
      setProvenanceLoading(false);
    }
  };

  const toggleProvenance = () => {
    const newState = !showProvenance();
    setShowProvenance(newState);
    if (newState) loadProvenance();
  };

  return (
    <Show when={!loading()} fallback={<LoadingSpinner />}>
      <Show
        when={!error() && synthesis()}
        fallback={
          <div class="max-w-4xl mx-auto px-4 py-12 text-center">
            <p class="text-red-600 mb-4">{error()}</p>
            <A href="/" class="text-indigo-600 hover:text-indigo-800 font-medium">
              &larr; {t('synthesis.backToHome')}
            </A>
          </div>
        }
      >
        {(synth) => (
          <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
            <div class="mb-8">
              {/* Top bar: back link + delete */}
              <div class="flex justify-between items-center mb-6">
                <A
                  href="/"
                  class="inline-flex items-center text-sm font-medium text-indigo-600 hover:text-indigo-800"
                >
                  <ArrowLeft class="mr-2 h-4 w-4" />
                  {t('synthesis.backLink')}
                </A>
                <button
                  onClick={() => setShowDeleteConfirm(true)}
                  class="inline-flex items-center text-sm font-medium text-red-600 hover:text-red-800"
                >
                  <Trash2 class="mr-1 h-4 w-4" />
                  {t('synthesis.delete')}
                </button>
              </div>

              {/* Delete confirmation banner */}
              <Show when={showDeleteConfirm()}>
                <div class="mb-6 bg-red-50 border border-red-200 rounded-lg p-4 flex flex-col sm:flex-row items-center justify-between gap-4">
                  <div class="flex items-center text-red-800">
                    <AlertTriangle class="h-5 w-5 mr-2 flex-shrink-0" />
                    <p class="text-sm">{t('synthesis.deleteConfirmMessage')}</p>
                  </div>
                  <div class="flex gap-3">
                    <button
                      onClick={() => setShowDeleteConfirm(false)}
                      disabled={isDeleting()}
                      class="px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 disabled:opacity-50"
                    >
                      {t('synthesis.deleteCancel')}
                    </button>
                    <button
                      onClick={handleDelete}
                      disabled={isDeleting()}
                      class="inline-flex items-center px-3 py-1.5 text-sm font-medium text-white bg-red-600 border border-transparent rounded-md hover:bg-red-700 disabled:opacity-50"
                    >
                      <Show when={isDeleting()}>
                        <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2" />
                      </Show>
                      {t('synthesis.deleteConfirm')}
                    </button>
                  </div>
                </div>
              </Show>

              {/* Title + date badge */}
              <div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
                <h1 class="text-3xl font-extrabold text-gray-900 tracking-tight">
                  {t('synthesis.title', { week: extractWeekNumber(synth().week) })}
                </h1>
                <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-gray-100 text-gray-800">
                  {t('synthesis.generatedAt', { date: formatDateLong(synth().created_at) })}
                </span>
              </div>

              {/* Email section */}
              <div class="mt-6 bg-white p-4 rounded-lg shadow-sm border border-gray-200">
                <div class="flex flex-col sm:flex-row items-center gap-4">
                  <div class="flex-1 w-full">
                    <label for="email-input" class="sr-only">
                      {t('synthesis.email.title')}
                    </label>
                    <div class="relative rounded-md shadow-sm">
                      <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                        <Mail class="h-5 w-5 text-gray-400" />
                      </div>
                      <input
                        type="email"
                        id="email-input"
                        class="focus:ring-indigo-500 focus:border-indigo-500 block w-full pl-10 sm:text-sm border-gray-300 rounded-md py-2 border"
                        placeholder={t('synthesis.email.placeholder')}
                        value={email()}
                        onInput={(e) => setEmail(e.currentTarget.value)}
                      />
                    </div>
                  </div>
                  <button
                    onClick={handleSendEmail}
                    disabled={sendingEmail() || !email()}
                    class="w-full sm:w-auto inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    <Show
                      when={!sendingEmail()}
                      fallback={
                        <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2" />
                      }
                    >
                      <Send class="h-4 w-4 mr-2" />
                    </Show>
                    {sendingEmail() ? t('synthesis.email.sending') : t('synthesis.email.send')}
                  </button>
                </div>

                {/* Email success message */}
                <Show when={emailSuccess()}>
                  <div class="mt-3 text-sm font-medium text-green-600 bg-green-50 p-3 rounded-md border border-green-200">
                    {t('synthesis.email.success')}
                  </div>
                </Show>

                {/* Email error message */}
                <Show when={emailError()}>
                  <div class="mt-3 text-sm font-medium text-red-600 bg-red-50 p-3 rounded-md border border-red-200">
                    {emailError()}
                  </div>
                </Show>
              </div>

              {/* Export section */}
              <div class="mt-4 bg-white p-4 rounded-lg shadow-sm border border-gray-200">
                <h3 class="text-sm font-medium text-gray-700 mb-3">
                  {t('synthesis.export.title')}
                </h3>
                <div class="flex flex-col sm:flex-row gap-3">
                  <button
                    onClick={handleExportMarkdown}
                    disabled={exportingMarkdown()}
                    class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    <Show
                      when={!exportingMarkdown()}
                      fallback={
                        <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-gray-500 mr-2" />
                      }
                    >
                      <FileDown class="h-4 w-4 mr-2" />
                    </Show>
                    {exportingMarkdown() ? t('synthesis.export.downloading') : t('synthesis.export.markdown')}
                  </button>
                  <button
                    onClick={handleExportPdf}
                    disabled={exportingPdf()}
                    class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
                  >
                    <Show
                      when={!exportingPdf()}
                      fallback={
                        <div class="animate-spin rounded-full h-4 w-4 border-b-2 border-gray-500 mr-2" />
                      }
                    >
                      <FileDown class="h-4 w-4 mr-2" />
                    </Show>
                    {exportingPdf() ? t('synthesis.export.downloading') : t('synthesis.export.pdf')}
                  </button>
                </div>

                {/* Export error message */}
                <Show when={exportError()}>
                  <div class="mt-3 text-sm font-medium text-red-600 bg-red-50 p-3 rounded-md border border-red-200">
                    {exportError()}
                  </div>
                </Show>
              </div>
            </div>

            {/* Sections */}
            <div class="space-y-12">
              <Show
                when={synth().sections && synth().sections.length > 0}
                fallback={
                  <p class="text-center text-gray-500 italic py-12">
                    {t('synthesis.noSections')}
                  </p>
                }
              >
                <For each={synth().sections}>
                  {(section) => <Section title={section.title} items={section.items} />}
                </For>
              </Show>
            </div>

            {/* Provenance */}
            <div class="mt-8 border-t pt-6">
              <button
                onClick={toggleProvenance}
                class="flex items-center text-sm font-medium text-gray-500 hover:text-gray-700"
              >
                <span class="mr-2">{showProvenance() ? '▼' : '▶'}</span>
                {t('articleHistory.provenance')}
                <Show when={provenance().length > 0}>
                  <span class="ml-2 text-xs text-gray-400">({provenance().length})</span>
                </Show>
              </button>
              <Show when={showProvenance()}>
                <Show when={provenanceLoading()}>
                  <LoadingSpinner />
                </Show>
                <Show when={!provenanceLoading() && provenance().length === 0}>
                  <p class="mt-4 text-sm text-gray-500">{t('articleHistory.provenanceEmpty')}</p>
                </Show>
                <Show when={!provenanceLoading() && provenance().length > 0}>
                  <div class="mt-4 overflow-x-auto">
                    <table class="min-w-full divide-y divide-gray-200 text-sm">
                      <thead class="bg-gray-50">
                        <tr>
                          <th class="px-3 py-2 text-left text-xs font-medium text-gray-500">{t('articleHistory.status')}</th>
                          <th class="px-3 py-2 text-left text-xs font-medium text-gray-500">{t('articleHistory.articleTitle')}</th>
                          <th class="px-3 py-2 text-left text-xs font-medium text-gray-500">{t('articleHistory.url')}</th>
                          <th class="px-3 py-2 text-left text-xs font-medium text-gray-500">{t('articleHistory.sourceType')}</th>
                          <th class="px-3 py-2 text-left text-xs font-medium text-gray-500">{t('articleHistory.category')}</th>
                        </tr>
                      </thead>
                      <tbody class="divide-y divide-gray-200">
                        <For each={provenance()}>
                          {(entry) => (
                            <tr>
                              <td class="px-3 py-2">
                                <span class={`inline-flex px-2 py-0.5 text-xs rounded-full ${
                                  entry.status === 'used' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
                                }`}>
                                  {entry.status}
                                </span>
                              </td>
                              <td class="px-3 py-2 max-w-xs truncate">{entry.title || '—'}</td>
                              <td class="px-3 py-2 max-w-xs truncate">
                                <a href={entry.url} target="_blank" rel="noopener noreferrer" class="text-indigo-600 hover:underline">
                                  {entry.url.length > 50 ? entry.url.slice(0, 50) + '...' : entry.url}
                                </a>
                              </td>
                              <td class="px-3 py-2">{entry.source_type}</td>
                              <td class="px-3 py-2">{entry.category || '—'}</td>
                            </tr>
                          )}
                        </For>
                      </tbody>
                    </table>
                  </div>
                </Show>
              </Show>
            </div>
          </div>
        )}
      </Show>
    </Show>
  );
};

export default SynthesisDetail;
