import React, { useEffect, useMemo, useState } from 'react';
import MainLayout from '../components/layout/MainLayout';
import { Box, Container, Heading, Text, Tabs, TabList, TabPanels, Tab, TabPanel, Table, Thead, Tbody, Tr, Th, Td, Flex, Spinner, Badge, Link, useColorModeValue } from '@chakra-ui/react';
import { getCompetitionAliasesPublic, CompetitionAlias } from '../services/competitionAliases';
import NewsletterCTA from '../components/common/NewsletterCTA';
import ClubModal from '../components/home/ClubModal';
import { usePublicSettings } from '../hooks/usePublicSettings';
import { sortCategoriesWithOrder } from '../utils/categorySort';
import { TeamLogo } from '../components/common/TeamLogo';
import { API_URL } from '../services/api';

type TableRow = {
  rank: string;
  team: string;
  team_id?: string;
  team_logo_url?: string;
  played: string;
  wins: string;
  draws: string;
  losses: string;
  score: string;
  points: string;
};

function deriveTeamIdFromLogoUrl(url?: string): string | undefined {
  try {
    const u = String(url || '');
    if (!u) return undefined;
    const m = u.match(/[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/);
    return m ? m[0].toLowerCase() : undefined;
  } catch {
    return undefined;
  }
}

type CompetitionTable = {
  id: string;
  name: string;
  code?: string;
  matches_link?: string;
  rows: TableRow[];
};

const resolveBackendUrl = (path: string) => {
  try {
    if (/^https?:\/\//i.test(path)) return path;
    if (path.startsWith('/cache') || path.startsWith('/uploads')) {
      const u = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : undefined);
      const abs = new URL(path, `${u.protocol}//${u.host}`);
      return abs.toString();
    }
    return path;
  } catch {
    return path;
  }
};

const TablesPage: React.FC = () => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [competitions, setCompetitions] = useState<CompetitionTable[]>([]);
  const [aliasMap, setAliasMap] = useState<Record<string, { alias: string; original_name?: string; display_order?: number }>>({});
  const [selectedClub, setSelectedClub] = useState<any>(null);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [overrides, setOverrides] = useState<{ by_id?: Record<string, { name?: string; logo_url?: string }>; by_name?: Record<string, string> } | null>(null);
  const { data: settings } = usePublicSettings();
  const cardBg = useColorModeValue('white', 'gray.800');
  const borderColor = useColorModeValue('gray.200', 'gray.700');
  const textSecondary = useColorModeValue('gray.600', 'gray.400');
  const tableBg = useColorModeValue('white', 'gray.800');
  const tableHeaderBg = useColorModeValue('var(--primary, #C53030)', 'var(--primary, #9b2c2c)');
  const tableTextColor = useColorModeValue('gray.800', 'gray.200');
  const rowOddBg = useColorModeValue('white', 'gray.800');
  const rowEvenBg = useColorModeValue('gray.50', 'gray.700');

  type SortKey = 'rank' | 'team' | 'played' | 'wins' | 'draws' | 'losses' | 'score' | 'points';
  type SortOrder = 'desc' | 'asc';
  const [sortState, setSortState] = useState<Record<string, { key: SortKey; order: SortOrder } | null>>({});
  const toNumber = (v: any): number => {
    if (typeof v === 'number') return v;
    const n = parseFloat(String(v ?? '').replace(/[^0-9\-\.]/g, ''));
    return isNaN(n) ? 0 : n;
  };
  const scoreDiff = (s: any): number => {
    const str = String(s ?? '').trim();
    const m = str.match(/(-?\d+)\s*[:\-]\s*(-?\d+)/);
    if (m) return Number(m[1]) - Number(m[2]);
    return toNumber(str);
  };
  const toggleSort = (compId: string, key: SortKey) => {
    const cur = sortState[compId];
    if (!cur || cur.key !== key) { setSortState({ ...sortState, [compId]: { key, order: 'desc' } }); return; }
    if (cur.order === 'desc') { setSortState({ ...sortState, [compId]: { key, order: 'asc' } }); return; }
    const next = { ...sortState }; next[compId] = null; setSortState(next);
  };
  const arrow = (compId: string, key: SortKey) => {
    const cur = sortState[compId];
    if (!cur || cur.key !== key) return '';
    return cur.order === 'desc' ? '▼' : '▲';
  };

  const handleClubClick = (club: any) => {
    setSelectedClub(club);
    setIsModalOpen(true);
  };

  useEffect(() => {
    let cancelled = false;
    (async () => {
      setLoading(true);
      setError(null);
      try {
        // Load overrides (API + cached file)
        try {
          const now = Date.now();
          let ovr: any = null;
          try {
            const res = await fetch(`/api/v1/public/team-logo-overrides?t=${now}`, { cache: 'no-cache' });
            if (res.ok) ovr = await res.json();
          } catch {}
          if (!ovr) {
            try {
              const res2 = await fetch('/cache/prefetch/team_logo_overrides.json', { cache: 'no-cache' });
              if (res2.ok) ovr = await res2.json();
            } catch {}
          }
          if (!cancelled) setOverrides(ovr || { by_id: {}, by_name: {} });
        } catch {}
        // Load aliases first
        let amap: Record<string, { alias: string; original_name?: string; display_order?: number }> = {};
        try {
          const aliases: CompetitionAlias[] = await getCompetitionAliasesPublic();
          (aliases || []).forEach((a) => { if (a?.code && a?.alias) amap[a.code] = { alias: a.alias, original_name: a.original_name, display_order: a.display_order }; });
        } catch {}
        const res = await fetch(resolveBackendUrl('/cache/prefetch/facr_tables.json'), { cache: 'no-cache' });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const json = await res.json();
        const comps: CompetitionTable[] = Array.isArray(json?.competitions)
          ? json.competitions.map((c: any, idx: number) => {
            const overall = c?.table?.overall || [];
            const rows: TableRow[] = Array.isArray(overall) ? overall.map((r: any) => ({
              rank: String(r.rank ?? ''),
              team: String(r.team ?? ''),
              team_id: r.team_id,
              team_logo_url: r.team_logo_url ? resolveBackendUrl(r.team_logo_url) : undefined,
              played: String(r.played ?? ''),
              wins: String(r.wins ?? ''),
              draws: String(r.draws ?? ''),
              losses: String(r.losses ?? ''),
              score: String(r.score ?? ''),
              points: String(r.points ?? ''),
            })) : [];
            return {
              id: String(c.id || idx),
              name: (amap?.[c?.code]?.alias) || (amap?.[String(c.id || idx)]?.alias) || c.name || c.code || `Soutěž ${idx+1}`,
              alias: (amap?.[c?.code]?.alias) || (amap?.[String(c.id || idx)]?.alias),
              display_order: (amap?.[c?.code]?.display_order) ?? (amap?.[String(c.id || idx)]?.display_order),
              code: c.code,
              matches_link: c.matches_link,
              rows,
            };
          }) : [];
        if (!cancelled) {
          setAliasMap(amap);
          // Only keep competitions that have at least one row in the table
          const filtered = (comps || []).filter((c) => Array.isArray(c.rows) && c.rows.length > 0);
          // Sort competitions by age (Muži first, then U19, U17, etc.) and respect custom order
          const sorted = sortCategoriesWithOrder(filtered) as typeof filtered;
          setCompetitions(sorted);
        }
      } catch (e: any) {
        if (!cancelled) setError(e?.message || 'Nepodařilo se načíst tabulky.');
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  // Normalization helpers (same as CalendarPage/TableSection)
  const normalize = (s: string) => String(s || '')
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/\s+/g, ' ')
    .trim()
    .toLowerCase();
  const stripPrefixes = (s: string) => {
    let x = normalize(s);
    x = x.replace(/\b(mestsky|m\.?f\.?k\.?|mfk|tj|sk|sokol|fotbalovy|fotbalový|fotbalovy\s+klub|fotbalovy\s+klub)\b/g, '');
    return x.replace(/\s+/g, ' ').trim();
  };
  const byNameMap = useMemo(() => {
    const m: Record<string, string> = {};
    const src = overrides?.by_name || {};
    for (const k of Object.keys(src)) m[normalize(k)] = src[k];
    return m;
  }, [overrides]);
  const byIdMap = useMemo(() => (overrides?.by_id || {}) as Record<string, { name?: string; logo_url?: string }>, [overrides]);
  const overridesNameIndex = useMemo(() => {
    const idx: Record<string, { id: string; name: string }> = {};
    try {
      for (const [id, v] of Object.entries(byIdMap)) {
        const name = String((v as any)?.name || '').trim();
        if (!name) continue;
        const key = normalize(name);
        if (!key) continue;
        idx[key] = { id, name };
      }
    } catch {}
    return idx;
  }, [byIdMap]);
  const pickName = (teamId?: string, original?: string, logoUrl?: string) => {
    const id = String(teamId || '') || deriveTeamIdFromLogoUrl(logoUrl) || '';
    const v = id ? byIdMap?.[id]?.name : undefined;
    if (v && String(v).trim().length > 0) return String(v);
    const orig = String(original || '');
    if (orig) {
      const n = normalize(orig);
      let hit = overridesNameIndex[n];
      if (!hit) {
        for (const [k, val] of Object.entries(overridesNameIndex)) {
          if (!k) continue;
          if (n.endsWith(k) || k.endsWith(n)) { hit = val as any; break; }
        }
      }
      if (!hit) {
        const t1 = n.split(' ')[0];
        if (t1 && t1.length >= 5) {
          for (const [k, val] of Object.entries(overridesNameIndex)) {
            const k1 = String(k).split(' ')[0];
            if (k1 === t1) { hit = val as any; break; }
          }
        }
      }
      if (hit?.name) return hit.name;
    }
    return orig;
  };
  const pickLogo = (teamId?: string, teamName?: string, original?: string): string | undefined => {
    if (teamId && byIdMap?.[teamId]?.logo_url) return byIdMap[teamId]!.logo_url as string;
    if (teamName) {
      const exact = (overrides?.by_name || {})[teamName];
      if (exact) return exact;
      const n = normalize(teamName);
      const cand = byNameMap[n];
      if (cand) return cand;
      const stripped = stripPrefixes(teamName);
      for (const k of Object.keys(overrides?.by_name || {})) {
        const kn = stripPrefixes(k);
        if (!kn) continue;
        if (stripped.endsWith(kn) || kn.endsWith(stripped)) return (overrides!.by_name as any)[k];
      }
    }
    return original;
  };

  return (
    <MainLayout>
      <Container maxW="7xl" py={{ base: 6, md: 10 }}>
        <Heading as="h1" size="xl" mb={2}>Tabulky</Heading>
        <Text color={textSecondary} mb={6}>Oficiální tabulky FACR podle soutěží.</Text>

        {loading && (
          <Flex align="center" gap={3} color={textSecondary} mb={6}>
            <Spinner size="sm" />
            <span>Načítám tabulky…</span>
          </Flex>
        )}
        {error && (
          <Box color="red.600" mb={6}>{error}</Box>
        )}

        {!!competitions.length && (
          <Tabs variant="enclosed" size="sm">
            <TabList px={2} pt={2} overflowX="auto" overflowY="hidden" css={{
              '&::-webkit-scrollbar': { height: '4px' },
              '&::-webkit-scrollbar-track': { background: 'transparent' },
              '&::-webkit-scrollbar-thumb': { background: 'var(--chakra-colors-gray-300)', borderRadius: '4px' },
            }}>
              {competitions.map((c) => (
                <Tab
                  key={c.id}
                  _selected={{ bg: 'brand.primary', color: 'text.onPrimary', borderColor: 'brand.primary' }}
                  _hover={{ bg: 'rgba(0,0,0,0.04)' }}
                  flex="0 0 auto"
                  px={3}
                  py={2}
                >
                  <Text as="span" noOfLines={1} maxW="300px" title={c.name}>{c.name}</Text>
                </Tab>
              ))}
            </TabList>
            <TabPanels>
              {competitions.map((c) => (
                <TabPanel key={c.id} px={0}>
                  <Flex align="center" justify="space-between" mb={3}>
                    <Heading as="h2" size="md">{c.name}</Heading>
                    {c.matches_link && (
                      <Link href={c.matches_link} isExternal color="brand.primary" _hover={{ filter: 'brightness(0.9)' }}>Rozpis a detail soutěže</Link>
                    )}
                  </Flex>
                  <Box borderWidth="1px" borderColor={borderColor} borderRadius="lg" overflowX="auto" boxShadow="sm" bg={tableBg}>
                    <Table size="sm" variant="unstyled" color={tableTextColor}>
                      <Thead position="sticky" top={0} zIndex={2}>
                        <Tr bg={tableHeaderBg} color="white">
                          <Th w="56px" color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'rank')}># {arrow(c.id, 'rank')}</Th>
                          <Th color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'team')}>Tým {arrow(c.id, 'team')}</Th>
                          <Th isNumeric color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'played')}>Z {arrow(c.id, 'played')}</Th>
                          <Th isNumeric color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'wins')}>V {arrow(c.id, 'wins')}</Th>
                          <Th isNumeric color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'draws')}>R {arrow(c.id, 'draws')}</Th>
                          <Th isNumeric color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'losses')}>P {arrow(c.id, 'losses')}</Th>
                          <Th isNumeric color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'score')}>Skóre {arrow(c.id, 'score')}</Th>
                          <Th isNumeric color="white" cursor="pointer" onClick={() => toggleSort(c.id, 'points')}>Body {arrow(c.id, 'points')}</Th>
                        </Tr>
                      </Thead>
                      <Tbody>
                        {(() => {
                          const cur = sortState[c.id];
                          const arr = [...(c.rows || [])];
                          if (cur) {
                            arr.sort((a: any, b: any) => {
                              let va: any; let vb: any; let isText = false;
                              switch (cur.key) {
                                case 'team': va = pickName(a.team_id, a.team, a.team_logo_url); vb = pickName(b.team_id, b.team, b.team_logo_url); isText = true; break;
                                case 'rank': va = toNumber(a.rank); vb = toNumber(b.rank); break;
                                case 'played': va = toNumber(a.played); vb = toNumber(b.played); break;
                                case 'wins': va = toNumber(a.wins); vb = toNumber(b.wins); break;
                                case 'draws': va = toNumber(a.draws); vb = toNumber(b.draws); break;
                                case 'losses': va = toNumber(a.losses); vb = toNumber(b.losses); break;
                                case 'score': va = scoreDiff(a.score); vb = scoreDiff(b.score); break;
                                case 'points': va = toNumber(a.points); vb = toNumber(b.points); break;
                                default: va = 0; vb = 0;
                              }
                              let res = isText ? String(va).localeCompare(String(vb)) : (va as number) - (vb as number);
                              if (cur.order === 'desc') res = -res;
                              if (res === 0) {
                                const ra = toNumber(a.rank); const rb = toNumber(b.rank);
                                res = ra - rb;
                              }
                              return res;
                            });
                          }
                          return arr.map((r, idx) => {
                          const displayTeam = pickName(r.team_id, r.team, r.team_logo_url);
                          const displayLogo = pickLogo(r.team_id, displayTeam, r.team_logo_url);
                          return (
                          <Tr 
                            key={`${c.id}-${r.rank}-${r.team}`} 
                            transition="all 0.15s" 
                            _hover={{ transform: 'translateY(-3px)', boxShadow: 'lg', zIndex: 3, cursor: 'pointer' }} 
                            position="relative" 
                            bg={idx % 2 === 0 ? rowOddBg : rowEvenBg}
                            onClick={() => handleClubClick(r)}
                          >
                            <Td>
                              <Badge variant="subtle" bg={useColorModeValue('gray.100', 'gray.700')} color={tableTextColor} borderWidth="1px" borderColor={borderColor}>{r.rank}</Badge>
                            </Td>
                            <Td>
                              <Flex align="center" gap={3}>
                                <TeamLogo
                                  teamId={r.team_id || deriveTeamIdFromLogoUrl(r.team_logo_url)}
                                  teamName={displayTeam}
                                  facrLogo={displayLogo}
                                  size="small"
                                  alt={displayTeam}
                                  objectFit="contain"
                                  bg={cardBg}
                                  borderWidth="1px"
                                  borderColor={borderColor}
                                />
                                <Text fontWeight="medium" color={tableTextColor}>{displayTeam}</Text>
                              </Flex>
                            </Td>
                            <Td isNumeric color={tableTextColor}>{r.played}</Td>
                            <Td isNumeric color={tableTextColor}>{r.wins}</Td>
                            <Td isNumeric color={tableTextColor}>{r.draws}</Td>
                            <Td isNumeric color={tableTextColor}>{r.losses}</Td>
                            <Td isNumeric color={tableTextColor}>{r.score}</Td>
                            <Td isNumeric>
                              <Badge variant="solid" bg="blue.600" color="white">{r.points}</Badge>
                            </Td>
                          </Tr>
                        );});})()}
                      </Tbody>
                    </Table>
                  </Box>
                </TabPanel>
              ))}
            </TabPanels>
          </Tabs>
        )}
        {!loading && !error && competitions.length === 0 && (
          <Text color={textSecondary}>Pro tento klub nejsou dostupné tabulky.</Text>
        )}
      </Container>
      
      {/* Newsletter CTA */}
      <NewsletterCTA />

      <ClubModal
        isOpen={isModalOpen}
        onClose={() => setIsModalOpen(false)}
        club={selectedClub}
        clubType={(settings?.club_type as 'football' | 'futsal') || 'football'}
      />
    </MainLayout>
  );
};

export default TablesPage;
