
"use client";

import { useEffect, useState } from 'react';
import Link from 'next/link';
import { motion, AnimatePresence, useMotionValue, useTransform } from 'motion/react';
import {
  getMatchHistory,
  removeMatchFromHistory,
  clearMatchHistory,
  type MatchHistoryEntry,
} from '@/lib/match-history';
import { useTranslation } from '@/lib/i18n/context';
import { shareViaNativeOrWeb } from '@/lib/share';

const SWIPE_DELETE_THRESHOLD = -70;

function formatRelativeTime(timestamp: number, t: ReturnType<typeof useTranslation>['t']): string {
  const diffMs = Date.now() - timestamp;
  const minutes = Math.floor(diffMs / 60000);
  const hours = Math.floor(diffMs / 3600000);
  const days = Math.floor(diffMs / 86400000);

  if (minutes < 1) return t.matchHistory.justNow;
  if (minutes < 60) return t.matchHistory.minutesAgo(minutes);
  if (hours < 24) return t.matchHistory.hoursAgo(hours);
  if (days === 1) return t.matchHistory.yesterday;
  return t.matchHistory.daysAgo(days);
}

function HeartIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="currentColor" aria-hidden="true">
      <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
    </svg>
  );
}

function JokerIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="currentColor" aria-hidden="true">
      <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8 0-1.69.53-3.25 1.43-4.54L8.5 14l1.29-1.29L12 15.21l2.21-2.5L15.5 14l3.07-6.54C19.47 8.75 20 10.31 20 12c0 4.41-3.59 8-8 8z" />
    </svg>
  );
}

function ShareIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
      <path
        strokeLinecap="round"
        strokeLinejoin="round"
        d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"
      />
    </svg>
  );
}

function TrashIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
      <path
        strokeLinecap="round"
        strokeLinejoin="round"
        d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
      />
    </svg>
  );
}

function CopyIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
      <rect x="9" y="9" width="11" height="11" rx="2" />
      <path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
    </svg>
  );
}

function PinIcon({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 24 24" className={className} fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true">
      <path d="M12 21s-7-5.5-7-11a7 7 0 0 1 14 0c0 5.5-7 11-7 11z" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx="12" cy="10" r="2.5" />
    </svg>
  );
}

/**
 * Animierter Mini-Karten-Stapel fuer den Empty-State - gleiche Motivsprache
 * wie der Hero-Stapel auf der Startseite, schwebt sanft auf und ab.
 */
function EmptyStateCardStack() {
  return (
    <motion.div
      animate={{ y: [0, -8, 0], rotate: [0, -3, 0] }}
      transition={{ duration: 3, repeat: Infinity, ease: 'easeInOut' }}
      className="relative w-24 h-32 mb-6"
    >
      <div className="absolute inset-0 bg-neutral-800 rounded-2xl rotate-[8deg] translate-x-3 translate-y-2 border border-neutral-700" />
      <div className="absolute inset-0 bg-yumder-teal/90 rounded-2xl -rotate-[6deg] -translate-x-3 translate-y-1 border border-yumder-teal" />
      <div className="absolute inset-0 bg-gradient-to-tr from-yumder-pink to-pink-500 rounded-2xl flex items-center justify-center shadow-2xl border border-pink-400/50">
        <HeartIcon className="w-10 h-10 text-white drop-shadow-md" />
      </div>
    </motion.div>
  );
}

// Avatar-Kuerzel: erster Buchstabe des Anzeigenamens, grossgeschrieben.
// Faellt auf "?" zurueck, wenn der Name leer ist (sollte nicht vorkommen).
function initialsOf(name: string): string {
  const trimmed = name.trim();
  if (!trimmed) return '?';
  return trimmed.charAt(0).toUpperCase();
}

// Dekorative Avatar-Farben (Brand-/Akzenttoene), per Index zugeordnet.
const AVATAR_COLORS = ['#FE3C72', '#00C2A8', '#8B5CF6', '#F59E0B', '#38BDF8'];

function HistoryRow({ entry, onRemove }: { entry: MatchHistoryEntry; onRemove: (id: string) => void }) {
  const { t } = useTranslation();
  const x = useMotionValue(0);
  const deleteOpacity = useTransform(x, [SWIPE_DELETE_THRESHOLD, 0], [1, 0]);
  const [copied, setCopied] = useState(false);
  const [codeCopied, setCodeCopied] = useState(false);

  async function handleShare() {
    const shareText = entry.address ? `${entry.name} \u2013 ${entry.address}` : entry.name;
    const handled = await shareViaNativeOrWeb({ title: entry.name, text: shareText });
    if (handled) return;
    try {
      await navigator.clipboard.writeText(shareText);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch {
      // Clipboard-API kann in seltenen Faellen fehlschlagen - dann einfach
      // stillschweigend nichts tun.
    }
  }

  async function handleCopyCode() {
    if (!entry.sessionCode) return;
    try {
      await navigator.clipboard.writeText(entry.sessionCode);
      setCodeCopied(true);
      setTimeout(() => setCodeCopied(false), 1800);
    } catch {
      // Clipboard-API kann in seltenen Faellen fehlschlagen - dann
      // stillschweigend nichts tun.
    }
  }

  return (
    <motion.li
      layout
      initial={{ opacity: 0, y: 6 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, x: -60, transition: { duration: 0.2 } }}
      className="relative overflow-hidden rounded-xl"
    >
      <motion.div
        style={{ opacity: deleteOpacity }}
        aria-hidden
        className="absolute inset-0 flex items-center justify-end pr-4 bg-yumder-pink rounded-xl"
      >
        <TrashIcon className="w-5 h-5 text-white" />
      </motion.div>

      <motion.div
        drag="x"
        style={{ x }}
        dragConstraints={{ left: SWIPE_DELETE_THRESHOLD - 8, right: 0 }}
        dragElastic={0.12}
        onDragEnd={(_, info) => {
          if (info.offset.x < SWIPE_DELETE_THRESHOLD) {
            onRemove(entry.id);
          }
        }}
        className="relative rounded-xl border border-white/5 bg-neutral-800 px-4 py-3 flex items-center gap-3 cursor-grab active:cursor-grabbing"
      >
        <div
          className={`shrink-0 w-10 h-10 rounded-full flex items-center justify-center ${
            entry.isJoker ? 'bg-amber-500 text-white' : 'bg-yumder-pink text-white'
          }`}
          aria-hidden="true"
        >
          {entry.isJoker ? <JokerIcon className="w-5 h-5" /> : <HeartIcon className="w-5 h-5" />}
        </div>

        <div className="flex flex-col min-w-0 flex-1 pr-2">
          <span className="font-semibold text-neutral-100 leading-snug">{entry.name}</span>
          {entry.address && (
            <span className="text-xs text-neutral-400 mt-0.5 truncate">{entry.address}</span>
          )}
          <span className="text-xs text-neutral-400 mt-0.5">{formatRelativeTime(entry.timestamp, t)}</span>

          {entry.participants && entry.participants.length > 0 && (
            <div className="flex items-center gap-2 mt-1.5">
              <div className="flex -space-x-1.5 shrink-0">
                {entry.participants.map((p, i) => (
                  <span
                    key={`${p}-${i}`}
                    className="w-5 h-5 rounded-full border border-neutral-900 flex items-center justify-center text-[9px] font-bold text-white"
                    style={{ backgroundColor: AVATAR_COLORS[i % AVATAR_COLORS.length] }}
                  >
                    {initialsOf(p)}
                  </span>
                ))}
              </div>
              <span className="text-[11px] text-neutral-400 leading-snug">
                {t.matchHistory.participantsLabel(entry.participants)}
              </span>
            </div>
          )}

          {entry.sessionCode && (
            <button
              type="button"
              onClick={handleCopyCode}
              className="mt-1.5 inline-flex items-center gap-1.5 self-start rounded-full bg-neutral-900 border border-white/10 px-2.5 py-1 text-[10px] font-semibold text-neutral-400 hover:border-yumder-teal/40 hover:text-neutral-200 transition-colors"
              aria-label={t.matchHistory.copySessionAriaLabel}
              title={t.matchHistory.copySessionAriaLabel}
            >
              <span className="font-mono font-bold tracking-widest">{entry.sessionCode}</span>
              {codeCopied ? (
                <span className="text-yumder-teal font-medium">{t.matchHistory.copiedLabel}</span>
              ) : (
                <CopyIcon className="w-3 h-3" />
              )}
            </button>
          )}
        </div>
        <div className="flex items-center gap-1 shrink-0">
          {copied && (
            <span className="text-[10px] text-yumder-teal font-medium whitespace-nowrap">
              {t.matchHistory.copiedLabel}
            </span>
          )}
          {entry.address && (
            <a
              href={`https://www.google.com/maps/search/${encodeURIComponent(`${entry.name} ${entry.address}`)}`}
              target="_blank"
              rel="noreferrer noopener"
              className="text-neutral-500 hover:text-yumder-teal transition-colors p-2 rounded-lg hover:bg-neutral-800"
              aria-label={t.matchHistory.openMapsAriaLabel}
              title={t.matchHistory.openMapsAriaLabel}
            >
              <PinIcon className="w-4 h-4" />
            </a>
          )}
          <button
            type="button"
            onClick={handleShare}
            className="text-neutral-500 hover:text-yumder-teal transition-colors p-2 rounded-lg hover:bg-neutral-800"
            aria-label={t.matchHistory.shareAriaLabel}
            title={t.matchHistory.shareAriaLabel}
          >
            <ShareIcon className="w-4 h-4" />
          </button>
          <button
            type="button"
            onClick={() => onRemove(entry.id)}
            className="text-neutral-500 hover:text-yumder-pink transition-colors p-2 rounded-lg hover:bg-neutral-800"
            aria-label={t.matchHistory.deleteEntryAriaLabel}
            title={t.matchHistory.deleteEntryAriaLabel}
          >
            <TrashIcon className="w-4 h-4" />
          </button>
        </div>
      </motion.div>
    </motion.li>
  );
}

/**
 * Zeigt die letzten Matches/Joker-Ergebnisse dieses Geraets auf dem
 * Start-Screen an, unterhalb von Erstellen/Beitreten. Reiner LocalStorage-
 * Stand, kein Server-Call. Wird befuellt aus session-client.tsx, sobald ein
 * neues Match ueber den Poll-Zyklus bestaetigt wird (siehe dort).
 *
 * UPDATE: Empty-State-Icon ersetzt (Karte mit hohlem Fragezeichen statt
 * Cloche/Teller) - siehe EmptyStateIcon oben.
 */
export function MatchHistory() {
  const { t } = useTranslation();
  const [entries, setEntries] = useState<MatchHistoryEntry[]>([]);
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setEntries(getMatchHistory());
    setMounted(true);
  }, []);

  function handleRemove(id: string) {
    setEntries(removeMatchFromHistory(id));
  }

  function handleClearAll() {
    setEntries(clearMatchHistory());
  }

  if (!mounted) return null;

  return (
    <div className="relative z-10 w-full max-w-sm flex flex-col gap-3">
      {entries.length > 0 && (
        <div className="flex justify-end">
          <button
            type="button"
            onClick={handleClearAll}
            className="text-xs font-semibold text-neutral-400 hover:text-yumder-pink transition-colors"
          >
            {t.matchHistory.clearAllLabel}
          </button>
        </div>
      )}

      {entries.length === 0 ? (
        <motion.div
          initial={{ opacity: 0, y: 10 }}
          animate={{ opacity: 1, y: 0 }}
          className="flex flex-col items-center justify-center py-10 px-4 text-center"
        >
          <EmptyStateCardStack />
          <h4 className="text-neutral-200 font-bold text-lg mb-1.5">{t.matchHistory.emptyTitle}</h4>
          <p className="text-neutral-400 text-sm max-w-xs leading-relaxed">{t.matchHistory.emptySubtitle}</p>
          <Link
            href="/"
            className="mt-6 inline-flex items-center justify-center rounded-xl px-6 py-3 text-sm font-semibold bg-gradient-to-r from-yumder-pink to-pink-500 shadow-[0_0_20px_rgba(254,60,114,0.35)]"
          >
            {t.matchHistory.emptyCta}
          </Link>
        </motion.div>
      ) : (
        <ul className="flex flex-col gap-2 list-none m-0 p-0">
          <AnimatePresence initial={false}>
            {entries.map((entry) => (
              <HistoryRow key={entry.id} entry={entry} onRemove={handleRemove} />
            ))}
          </AnimatePresence>
        </ul>
      )}
    </div>
  );
}
