import { useState, useEffect, useCallback, useRef } from 'react';
import { api, Match } from '../api/client';
import MatchCard from '../components/MatchCard';
import TipModal from '../components/TipModal';
import styles from './MatchesPage.module.css';

const STAGES: { key: string; label: string }[] = [
  { key: '', label: 'Alle' },
  { key: 'GROUP_STAGE', label: 'Gruppenphase' },
  { key: 'LAST_32', label: 'Runde der 32' },
  { key: 'LAST_16', label: 'Achtelfinale' },
  { key: 'QUARTER_FINALS', label: 'Viertelfinale' },
  { key: 'SEMI_FINALS', label: 'Halbfinale' },
  { key: 'THIRD_PLACE', label: 'Platz 3' },
  { key: 'FINAL', label: 'Finale' },
];

const GROUPS = ['A','B','C','D','E','F','G','H','I','J','K','L'];

export default function MatchesPage() {
  const [allMatches, setAllMatches] = useState<Match[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [stage, setStage] = useState('');
  const [group, setGroup] = useState('');
  const [selectedMatch, setSelectedMatch] = useState<Match | null>(null);
  const todayRef = useRef<HTMLDivElement | null>(null);
  const hasScrolled = useRef(false);

  // Alle Spiele einmalig laden — Filterung passiert im Frontend
  const loadMatches = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await api.getMatches();
      setAllMatches(res.matches);
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => { loadMatches(); }, [loadMatches]);

  // Auto-Scroll zum heutigen Datum nach dem ersten Laden
  useEffect(() => {
    if (!loading && !hasScrolled.current && todayRef.current && !stage) {
      hasScrolled.current = true;
      setTimeout(() => {
        todayRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
      }, 100);
    }
  }, [loading, stage]);

  const handleTipSaved = (matchId: number, tipHome: number, tipAway: number) => {
    setAllMatches(prev => prev.map(m =>
      m.id === matchId
        ? { ...m, userTip: { home: tipHome, away: tipAway, points: null } }
        : m
    ));
    setSelectedMatch(null);
  };

  // Gefilterte Matches für aktuelle Ansicht
  const matches = allMatches
    .filter(m => !stage || m.stage === stage)
    .filter(m => !group || m.group === `GROUP_${group}`);

  // Stats immer über alle Spiele (nicht gefiltert)
  const tipped   = allMatches.filter(m => m.userTip).length;
  const tippable = allMatches.filter(m => m.tippable && !m.userTip).length;

  // Verfügbare Gruppen für den aktiven Stage-Filter
  const availableGroups = stage === 'GROUP_STAGE'
    ? [...new Set(allMatches
        .filter(m => m.stage === 'GROUP_STAGE' && m.group)
        .map(m => m.group!.replace('GROUP_', ''))
      )].sort()
    : [];

  // Spiele nach Datum gruppieren (Gruppenphase) oder nach Gruppe (wenn Gruppe gewählt)
  const grouped = matches.reduce<Record<string, Match[]>>((acc, m) => {
    let key: string;
    if (stage === 'GROUP_STAGE' && !group) {
      // Gruppenphase ohne Gruppen-Filter: nach Gruppe gruppieren
      key = `Gruppe ${m.group?.replace('GROUP_', '') ?? '?'}`;
    } else {
      // Sonst nach Datum
      key = new Date(m.utcDate).toLocaleDateString('de-DE', {
        weekday: 'long', day: 'numeric', month: 'long'
      });
    }
    if (!acc[key]) acc[key] = [];
    acc[key].push(m);
    return acc;
  }, {});

  return (
    <div className={styles.page}>
      {/* Header Stats */}
      <div className={styles.statsRow}>
        <div className={`card ${styles.statCard}`}>
          <span className={styles.statValue}>{matches.length}</span>
          <span className={styles.statLabel}>Spiele gesamt</span>
        </div>
        <div className={`card ${styles.statCard}`}>
          <span className={`${styles.statValue} text-primary`}>{tipped}</span>
          <span className={styles.statLabel}>Tipps abgegeben</span>
        </div>
        <div className={`card ${styles.statCard}`}>
          <span className={`${styles.statValue} text-gold`}>{tippable}</span>
          <span className={styles.statLabel}>Noch tippbar</span>
        </div>
      </div>

      {/* Stage Filter */}
      <div className={styles.filters}>
        {STAGES.map(s => (
          <button
            key={s.key}
            className={stage === s.key ? styles.filterActive : styles.filter}
            onClick={() => { setStage(s.key); setGroup(''); }}
          >
            {s.label}
          </button>
        ))}
      </div>

      {/* Gruppen-Filter (nur bei Gruppenphase) */}
      {availableGroups.length > 0 && (
        <div className={styles.groupFilters}>
          <button
            className={group === '' ? styles.groupFilterActive : styles.groupFilter}
            onClick={() => setGroup('')}
          >
            Alle Gruppen
          </button>
          {availableGroups.map(g => (
            <button
              key={g}
              className={group === g ? styles.groupFilterActive : styles.groupFilter}
              onClick={() => setGroup(g)}
            >
              Gruppe {g}
            </button>
          ))}
        </div>
      )}

      {/* Content */}
      {loading && (
        <div className={styles.loadingState}>
          <div className={styles.spinner} />
          <span>Spiele werden geladen…</span>
        </div>
      )}

      {error && (
        <div className={styles.errorState}>
          <span>⚠️ {error}</span>
          <button className="btn-ghost" onClick={loadMatches}>Erneut versuchen</button>
        </div>
      )}

      {!loading && !error && matches.length === 0 && (
        <div className={styles.emptyState}>
          <span className={styles.emptyIcon}>⚽</span>
          <p>Noch keine Spiele vorhanden.</p>
          <p className={styles.emptyHint}>
            Geh auf die Admin-Seite und klicke "Spiele synchronisieren".
          </p>
        </div>
      )}

      {!loading && !error && (() => {
        const entries = Object.entries(grouped);
        if (stage === 'GROUP_STAGE' && !group) {
          entries.sort(([a], [b]) => a.localeCompare(b));
        }

        const todayLabel = new Date().toLocaleDateString('de-DE', {
          weekday: 'long', day: 'numeric', month: 'long'
        });

        // "Nächster bevorstehender Tag" als Fallback wenn kein heutiger Spieltag
        let scrollTarget: string | null = null;
        if (!stage) {
          if (entries.find(([l]) => l === todayLabel)) {
            scrollTarget = todayLabel;
          } else {
            const now = Date.now();
            const future = entries.find(([, ms]) => new Date(ms[0].utcDate).getTime() > now);
            scrollTarget = future?.[0] ?? null;
          }
        }

        return entries.map(([label, labelMatches]) => {
          const isScrollTarget = label === scrollTarget;
          return (
            <div
              key={label}
              className={styles.dayGroup}
              ref={isScrollTarget ? todayRef : null}
            >
              <h2 className={styles.dayHeader}>
                {label === todayLabel ? (
                  <><span className={styles.todayDot} />Heute — {label}</>
                ) : label}
              </h2>
              <div className={styles.matchList}>
                {labelMatches
                  .sort((a, b) => new Date(a.utcDate).getTime() - new Date(b.utcDate).getTime())
                  .map(match => (
                    <MatchCard
                      key={match.id}
                      match={match}
                      onTip={() => setSelectedMatch(match)}
                    />
                ))}
              </div>
            </div>
          );
        });
      })()}

      {selectedMatch && (
        <TipModal
          match={selectedMatch}
          onClose={() => setSelectedMatch(null)}
          onSaved={handleTipSaved}
        />
      )}
    </div>
  );
}
