"use client";

import { useEffect, useId, useRef, useState } from 'react';
import { useParams, useRouter } from 'next/navigation';
import Link from 'next/link';
import { CUISINE_OPTIONS } from '@/lib/cuisine';
import { SponsorFormModal } from '@/components/sponsor-form-modal';
import { Bar } from 'react-chartjs-2';
import {
  Chart as ChartJS, CategoryScale, LinearScale, BarElement, Tooltip, Legend,
} from 'chart.js';
import 'funnel-graph-js/dist/css/main.min.css';
import 'funnel-graph-js/dist/css/theme.min.css';

ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip, Legend);

interface DailyTrendRow {
  day: string;
  impressions: number;
  yes_swipes: number;
  matches: number;
}

interface SponsorDetail {
  id: number;
  restaurant_id: number | null;
  name: string;
  image_url: string | null;
  address: string | null;
  city: string | null;
  postal_code: string | null;
  lat: number | null;
  lon: number | null;
  filter_cuisine_tags: string | null;
  discount_text: string | null;
  priority: number;
  active: number;
  active_from: string | null;
  active_until: string | null;
  impressions: number;
  yesSwipes: number;
  matches: number;
}

function cuisineLabelFromTags(tagsJson: string | null): string {
  if (!tagsJson) return 'Ohne Kategorie';
  try {
    const tags: string[] = JSON.parse(tagsJson);
    if (tags.length === 0) return 'Ohne Kategorie';
    const opt = CUISINE_OPTIONS.find((o) => o.value === tags[0]);
    return opt?.label ?? tags[0];
  } catch {
    return 'Ohne Kategorie';
  }
}

function isExpired(activeUntil: string | null): boolean {
  if (!activeUntil) return false;
  return new Date(activeUntil) < new Date();
}

function boostLabelFromPriority(priority: number): string {
  if (priority >= 8) return 'Boost 3x';
  if (priority >= 4) return 'Boost 2x';
  return 'Boost 1x';
}

function formatDateDe(dateStr: string): string {
  return new Date(dateStr).toLocaleDateString('de-DE');
}

// BUGFIX (v20, Farbe): Fuer einen EINFACHEN (nicht zweidimensionalen)
// Trichter erwartet funnel-graph-js ein FLACHES colors-Array, das als EIN
// durchgehender Gradient ueber den GESAMTEN Trichter verlaeuft - nicht ein
// verschachteltes Array pro Segment (das ist nur fuer 2D-Trichter mit
// subLabels gedacht, siehe offizielle Doku-Beispiele). v17/v19 nutzten
// faelschlich das verschachtelte Format, wodurch die Library intern auf
// Schwarz zurueckfiel. Jetzt: colors: ['#3b82f6', '#FE3C72', '#00C2A8'] als
// ein Verlauf durch alle drei Marken-Farben.
//
// BUGFIX (v20, Kontrast): Die von funnel-graph-js erzeugten Wert-Labels
// (class="label__value" laut Library-Quellcode) erben eine helle Textfarbe
// aus dem mitgelieferten theme.css, die auf hellem Hintergrund kaum lesbar
// ist. Per <style jsx global>-Block gezielt auf dunklen Admin-Text
// (var(--admintext) existiert nicht als CSS-Var, daher direkter Hex-Wert)
// umgestellt, nur innerhalb des Funnel-Containers (kein globaler Eingriff).
function FunnelChart({ impressions, yesSwipes, matches }: { impressions: number; yesSwipes: number; matches: number }) {
  const rawId = useId();
  const containerId = `funnel-${rawId.replace(/:/g, '')}`;
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (impressions === 0 || !containerRef.current) return;

    let mounted = true;
    import('funnel-graph-js').then(({ default: FunnelGraph }) => {
      if (!mounted || !containerRef.current) return;
      containerRef.current.innerHTML = '';
      try {
        const graph = new FunnelGraph({
          container: `#${containerId}`,
          gradientDirection: 'horizontal',
          data: {
            labels: ['Swipes', '"Ja"-Swipes', 'Matches'],
            colors: ['#3b82f6', '#FE3C72', '#00C2A8'],
            values: [impressions, yesSwipes, matches],
          },
          displayPercent: true,
          direction: 'horizontal',
          height: 260,
        });
        graph.draw();
      } catch (e) {
        console.error('Funnel-Diagramm konnte nicht gezeichnet werden:', e);
      }
    });

    return () => {
      mounted = false;
      if (containerRef.current) containerRef.current.innerHTML = '';
    };
  }, [impressions, yesSwipes, matches, containerId]);

  if (impressions === 0) {
    return <p className="text-sm text-adminmuted">Noch keine Swipe-Daten für diese Kampagne.</p>;
  }

  const yesPct = Math.round((yesSwipes / impressions) * 1000) / 10;
  const matchPct = Math.round((matches / impressions) * 1000) / 10;

  return (
    <>
      <div id={containerId} ref={containerRef} className="funnel w-full" />
      {/* Kontrast-Fix: mehrere gaengige funnel-graph-js-Klassennamen
          abgedeckt, damit der Fix greift, egal welche Version/Variante der
          Library tatsaechlich rendert. */}
      <style jsx global>{`
        #${containerId} .label__value,
        #${containerId} .label__title,
        #${containerId} .svg-funnel-js__label .label__value,
        #${containerId} .svg-funnel-js__label .label__title {
          color: #18181b !important;
        }
        #${containerId} .label__percentage {
          color: #52525b !important;
        }
      `}</style>
      <div className="mt-3 pt-4 border-t border-adminborder grid grid-cols-2 gap-3 text-sm">
        <div>
          <span className="text-adminmuted">"Ja"-Quote: </span>
          <strong className="text-yumder-pink">{yesPct}%</strong>
          <span className="text-adminmuted"> der Swipes</span>
        </div>
        <div>
          <span className="text-adminmuted">Match-Quote: </span>
          <strong className="text-yumder-teal">{matchPct}%</strong>
          <span className="text-adminmuted"> der Swipes</span>
        </div>
      </div>
    </>
  );
}

export default function SponsorDetailPage() {
  const params = useParams<{ id: string }>();
  const router = useRouter();
  const [sponsor, setSponsor] = useState<SponsorDetail | null>(null);
  const [trend, setTrend] = useState<DailyTrendRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [notFound, setNotFound] = useState(false);
  const [showForm, setShowForm] = useState(false);

  async function loadSponsor() {
    setLoading(true);
    try {
      const res = await fetch(`/api/admin/sponsors/${params.id}`);
      if (res.status === 401) {
        router.push('/admin');
        return;
      }
      if (res.status === 404) {
        setNotFound(true);
        return;
      }
      const data = await res.json();
      setSponsor(data.sponsor);
      setTrend(data.trend ?? []);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => { loadSponsor(); }, [params.id]);

  if (loading) {
    return (
      <div className="p-6 lg:p-8 pb-24">
        <div className="max-w-4xl mx-auto">
          <p className="text-adminmuted text-sm">Lade Kampagne...</p>
        </div>
      </div>
    );
  }

  if (notFound || !sponsor) {
    return (
      <div className="p-6 lg:p-8 pb-24">
        <div className="max-w-4xl mx-auto">
          <p className="text-adminmuted text-sm mb-4">Diese Kampagne wurde nicht gefunden.</p>
          <Link href="/admin/dashboard/sponsors" className="text-yumder-pink font-semibold text-sm hover:underline">
            ← Zurück zur Übersicht
          </Link>
        </div>
      </div>
    );
  }

  const expired = isExpired(sponsor.active_until);
  const statusLabel = expired ? 'Abgelaufen' : sponsor.active === 1 ? 'Aktiv' : 'Pausiert';
  const statusCls = expired || sponsor.active !== 1 ? 'bg-adminmuted' : 'bg-adminsuccess';

  return (
    <div className="p-6 lg:p-8 pb-24">
      <div className="max-w-4xl mx-auto">
        <Link
          href="/admin/dashboard/sponsors"
          className="inline-flex items-center gap-1.5 text-sm text-adminmuted hover:text-yumder-pink transition-colors mb-4"
        >
          ← Zurück zur Übersicht
        </Link>

        <div className="glass overflow-hidden mb-6">
          <div className="relative w-full h-56 bg-adminborder">
            {sponsor.image_url ? (
              <img src={sponsor.image_url} alt={sponsor.name} className="w-full h-full object-cover" />
            ) : (
              <div className="w-full h-full flex items-center justify-center text-adminmuted text-sm">
                Kein Bild
              </div>
            )}
            <span
              className={`absolute top-4 right-4 px-3 py-1.5 rounded-full text-xs font-bold text-white shadow-[0_8px_20px_-4px_rgba(254,60,114,0.55)] ${statusCls}`}
            >
              {statusLabel}
            </span>
          </div>

          <div className="p-6 lg:p-8">
            <div className="flex flex-wrap items-start justify-between gap-4 mb-4">
              <div>
                <h1 className="text-2xl font-bold text-admintext mb-1">{sponsor.name}</h1>
                <p className="text-sm text-adminmuted">
                  {[sponsor.postal_code, sponsor.city].filter(Boolean).join(' ') || '–'} • {cuisineLabelFromTags(sponsor.filter_cuisine_tags)} • {boostLabelFromPriority(sponsor.priority)}
                </p>
                <p className={`text-xs mt-1.5 font-semibold ${sponsor.restaurant_id ? 'text-yumder-teal' : 'text-adminmuted'}`}>
                  {sponsor.restaurant_id ? 'Mit Restaurant-Daten verknüpft' : 'Nicht verknüpft (keine Live-Stats)'}
                </p>
              </div>
              <button
                onClick={() => setShowForm(true)}
                className="shrink-0 bg-yumder-pink text-white font-semibold text-sm px-5 py-2.5 rounded-lg hover:opacity-90 transition-opacity"
              >
                Bearbeiten
              </button>
            </div>

            {sponsor.discount_text && (
              <p className="inline-flex items-center gap-1 bg-adminbg text-amber-600 text-sm font-semibold px-3 py-1.5 rounded-md mb-4">
                {sponsor.discount_text}
              </p>
            )}

            {sponsor.active_until && (
              <p className={`text-xs mb-2 font-semibold ${expired ? 'text-admindanger' : 'text-adminmuted'}`}>
                {expired
                  ? `Abgelaufen am ${formatDateDe(sponsor.active_until)}`
                  : `Läuft bis: ${formatDateDe(sponsor.active_until)}`}
              </p>
            )}
          </div>
        </div>

        {/* ENTFERNT (v20): die drei separaten KPI-Kacheln (Swipes/"Ja"-
            Swipes/Matches). Der Trichter darunter zeigt dieselben absoluten
            Werte bereits selbst als Labels - die Kacheln waren damit reine
            Redundanz, wie im Feedback angemerkt. */}

        <div className="glass p-6 lg:p-8">
          <p className="text-xs text-adminmuted uppercase tracking-widest font-bold mb-6">
            Performance-Trichter · Lifetime
          </p>
          <FunnelChart impressions={sponsor.impressions} yesSwipes={sponsor.yesSwipes} matches={sponsor.matches} />
        </div>

        <div className="glass p-6 lg:p-8">
          <p className="text-xs text-adminmuted uppercase tracking-widest font-bold mb-6">
            Performance-Verlauf · letzte 30 Tage
          </p>
          {sponsor.restaurant_id ? (
            trend.length > 0 ? (
              <div className="h-64">
                <Bar
                  data={{
                    labels: trend.map((t) => t.day),
                    datasets: [
                      { label: 'Swipes', data: trend.map((t) => t.impressions), backgroundColor: '#3b82f6', borderRadius: 4 },
                      { label: '"Ja"-Swipes', data: trend.map((t) => t.yes_swipes), backgroundColor: '#FE3C72', borderRadius: 4 },
                      { label: 'Matches', data: trend.map((t) => t.matches), backgroundColor: '#00C2A8', borderRadius: 4 },
                    ],
                  }}
                  options={{
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: { legend: { position: 'top', labels: { usePointStyle: true, boxWidth: 8 } } },
                    scales: {
                      y: { beginAtZero: true, grid: { color: '#e9ecef' }, ticks: { precision: 0 } },
                      x: { grid: { display: false } },
                    },
                  }}
                />
              </div>
            ) : (
              <p className="text-sm text-adminmuted">Noch keine Zeitreihen-Daten für diese Kampagne.</p>
            )
          ) : (
            <p className="text-sm text-adminmuted">Diese Kampagne ist mit keinem Restaurant verknüpft – daher keine Zeitreihe.</p>
          )}
        </div>
      </div>

      {showForm && (
        <SponsorFormModal
          sponsorToEdit={sponsor}
          onClose={() => setShowForm(false)}
          onSaved={loadSponsor}
        />
      )}
    </div>
  );
}
