import React, { useEffect, useMemo, useState } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import MainLayout from '../components/layout/MainLayout';
import {
  Box,
  Container,
  Heading,
  Text,
  Tabs,
  TabList,
  TabPanels,
  Tab,
  TabPanel,
  Flex,
  Badge,
  Stack,
  Spinner,
  Grid,
  IconButton,
  ButtonGroup,
  Button,
  useToast,
  Select,
  useColorModeValue,
} from '@chakra-ui/react';
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
import { addMonths, format, isSameDay, isSameMonth, startOfMonth, startOfWeek } from 'date-fns';
import { cs } from 'date-fns/locale';
import { getEvents } from '../services/eventService';

// Weekday headers (Czech, starting Monday)
const WEEKDAYS_SHORT: string[] = ['Po', 'Út', 'St', 'Čt', 'Pá', 'So', 'Ne'];

type UiEvent = {
  id: number | string;
  title: string;
  start_time: string; // ISO
  end_time?: string | null;
  location?: string | null;
  type?: 'match' | 'training' | 'meeting' | 'other' | string;
  image_url?: string | null;
};

const typeLabel = (t?: string) => (t === 'match' ? 'Zápas' : t === 'training' ? 'Trénink' : t === 'meeting' ? 'Schůzka' : 'Jiné');
const typeColor = (t?: string) => (t === 'match' ? 'red' : t === 'training' ? 'blue' : t === 'meeting' ? 'green' : 'gray');

const toDateKey = (iso: string) => {
  try { return format(new Date(iso), 'yyyy-MM-dd'); } catch { return iso.slice(0, 10); }
};

const ActivitiesCalendarPage: React.FC = () => {
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [events, setEvents] = useState<UiEvent[]>([]);
  const [filter, setFilter] = useState<'all' | 'match' | 'training' | 'meeting' | 'other'>('all');
  const [viewMode, setViewMode] = useState<'calendar' | 'list'>('calendar');
  const toast = useToast();

  const mutedText = useColorModeValue('gray.600', 'gray.300');
  const subtleText = useColorModeValue('gray.500', 'gray.400');
  const borderColor = useColorModeValue('rgba(0,0,0,0.08)', 'rgba(255,255,255,0.16)');
  const cardBg = useColorModeValue('white', 'gray.800');
  const hoverBg = useColorModeValue('rgba(0,0,0,0.03)', 'rgba(255,255,255,0.08)');
  const listHeaderBg = useColorModeValue('gray.50', 'whiteAlpha.100');
  const todayHighlightBg = useColorModeValue('rgba(59,130,246,0.08)', 'rgba(59,130,246,0.16)');

  // Calendar state
  const [monthRef, setMonthRef] = useState<Date>(startOfMonth(new Date()));
  const weeks = useMemo(() => {
    const start = startOfWeek(startOfMonth(monthRef), { weekStartsOn: 1 });
    const days: Date[] = [];
    for (let i = 0; i < 42; i++) days.push(new Date(start.getTime() + i * 86400000));
    return days;
  }, [monthRef]);

  const filtered = useMemo(() => (filter === 'all' ? events : events.filter((e) => e.type === filter)), [events, filter]);

  const byDate = useMemo(() => {
    const map = new Map<string, UiEvent[]>();
    filtered.forEach((e) => {
      const startKey = toDateKey(e.start_time);
      const endKey = e.end_time ? toDateKey(e.end_time) : startKey;

      if (startKey === endKey) {
        map.set(startKey, [...(map.get(startKey) || []), e]);
        return;
      }

      const startDate = new Date(startKey);
      const endDate = new Date(endKey);
      if (Number.isNaN(startDate.getTime()) || Number.isNaN(endDate.getTime())) {
        map.set(startKey, [...(map.get(startKey) || []), e]);
        return;
      }

      for (let d = new Date(startDate); d.getTime() <= endDate.getTime(); d.setDate(d.getDate() + 1)) {
        const key = format(d, 'yyyy-MM-dd');
        map.set(key, [...(map.get(key) || []), e]);
      }
    });

    // Sort events within each date by time
    Array.from(map.keys()).forEach((key) => {
      const list = map.get(key) || [];
      list.sort((a, b) => new Date(a.start_time).getTime() - new Date(b.start_time).getTime());
      map.set(key, list);
    });
    return map;
  }, [filtered]);

  useEffect(() => {
    let active = true;
    (async () => {
      setLoading(true);
      setError(null);
      try {
        const evs = await getEvents();
        const mapped: UiEvent[] = (evs || []).map((e: any) => ({
          id: e.id,
          title: e.title,
          start_time: e.start_time,
          end_time: e.end_time,
          location: e.location,
          type: e.type,
          image_url: e.image_url,
        }));
        if (active) setEvents(mapped);
      } catch (e: any) {
        if (active) setError(e?.message || 'Nepodařilo se načíst aktivity.');
      } finally {
        if (active) setLoading(false);
      }
    })();
    return () => { active = false; };
  }, []);

  const hasData = filtered.length > 0;

  return (
    <MainLayout>
      <Container maxW="7xl" py={{ base: 6, md: 10 }}>
        <Heading as="h1" size="xl" mb={2}>Aktivity</Heading>
        <Text color={mutedText} mb={6}>Kalendář tréninků, schůzek a dalších klubových aktivit.</Text>

        <Flex align="center" justify="space-between" mb={3} gap={2} flexWrap={{ base: 'wrap', md: 'nowrap' }}>
          <Flex align="center" gap={2}>
            <Select size="sm" value={filter} onChange={(e) => setFilter(e.target.value as any)} width={{ base: '100%', sm: '220px' }}>
              <option value="all">Všechny typy</option>
              <option value="match">Zápasy</option>
              <option value="training">Tréninky</option>
              <option value="meeting">Schůzky</option>
              <option value="other">Ostatní</option>
            </Select>
          </Flex>
          <ButtonGroup size="sm" isAttached>
            <Button
              variant={viewMode==='calendar' ? 'solid' : 'outline'}
              bg={viewMode==='calendar' ? 'brand.primary' : undefined}
              color={viewMode==='calendar' ? 'text.onPrimary' : undefined}
              _hover={{ filter: viewMode==='calendar' ? 'brightness(0.95)' : undefined, borderColor: 'brand.primary', color: viewMode==='calendar' ? 'text.onPrimary' : undefined }}
              onClick={() => setViewMode('calendar')}
            >Kalendář</Button>
            <Button
              variant={viewMode==='list' ? 'solid' : 'outline'}
              bg={viewMode==='list' ? 'brand.primary' : undefined}
              color={viewMode==='list' ? 'text.onPrimary' : undefined}
              _hover={{ filter: viewMode==='list' ? 'brightness(0.95)' : undefined, borderColor: 'brand.primary', color: viewMode==='list' ? 'text.onPrimary' : undefined }}
              onClick={() => setViewMode('list')}
            >Seznam</Button>
          </ButtonGroup>
        </Flex>

        {loading && (
          <Flex align="center" gap={3} color={mutedText} mb={6}>
            <Spinner size="sm" />
            <span>Načítám aktivity…</span>
          </Flex>
        )}

        {error && (
          <Box color="red.400" mb={4}>{error}</Box>
        )}

        {!loading && !hasData && !error && (
          <Box color={mutedText}>Zatím nemáme žádné aktivity k zobrazení.</Box>
        )}

        {!loading && hasData && (
          viewMode === 'calendar' ? (
            <>
              <Flex align="center" justify="space-between" mb={3} gap={2} flexWrap={{ base: 'wrap', md: 'nowrap' }}>
                <IconButton
                  aria-label="Předchozí měsíc"
                  size="sm"
                  onClick={() => setMonthRef(addMonths(monthRef, -1))}
                  icon={<ChevronLeftIcon />}
                  variant="outline"
                  _hover={{ bg: 'rgba(0,0,0,0.04)', borderColor: 'brand.primary' }}
                />
                <Button
                  size="sm"
                  onClick={() => setMonthRef(new Date())}
                  variant="solid"
                  bg={'brand.primary'}
                  color={'text.onPrimary'}
                  _hover={{ filter: 'brightness(0.95)' }}
                >Dnes</Button>
                <IconButton
                  aria-label="Další měsíc"
                  size="sm"
                  onClick={() => setMonthRef(addMonths(monthRef, 1))}
                  icon={<ChevronRightIcon />}
                  variant="outline"
                  _hover={{ bg: 'rgba(0,0,0,0.04)', borderColor: 'brand.primary' }}
                />
              </Flex>
              <Box overflowX="auto">
                <Grid templateColumns="repeat(7, 1fr)" gap={3} minW="980px">
                  {WEEKDAYS_SHORT.map((w) => (
                    <Box key={w} textAlign="center" fontWeight="semibold" color={mutedText} fontSize={{ base: 'xs', md: 'sm' }}>{w}</Box>
                  ))}
                </Grid>
              </Box>
              <Box overflowX="auto">
                <Grid templateColumns="repeat(7, 1fr)" gap={{ base: 1, md: 2 }} minW="980px">
                  {weeks.map((day, idx) => {
                    const key = format(day, 'yyyy-MM-dd');
                    const list = byDate.get(key) || [];
                    const faded = !isSameMonth(day, monthRef);
                    const today = isSameDay(day, new Date());
                    return (
                      <Box
                        key={idx}
                        borderWidth="1px"
                        borderColor={today ? 'brand.primary' : borderColor}
                        borderRadius="md"
                        p={2}
                        minH="120px"
                        minW="130px"
                        bg={today ? todayHighlightBg : undefined}
                        opacity={faded ? 0.6 : 1}
                      >
                        <Flex align="center" justify="space-between" mb={2}>
                          <Text fontWeight="bold">{format(day, 'd')}</Text>
                          {!!list.length && (
                            <Badge bg="brand.primary" color="text.onPrimary" borderRadius="full">{list.length}</Badge>
                          )}
                        </Flex>
                        <Stack spacing={2}>
                          {list.slice(0, 3).map((e) => (
                            <Box
                              key={e.id}
                              as={RouterLink}
                              to={`/aktivita/${e.id}`}
                              p={2}
                              borderWidth="1px"
                              borderRadius="md"
                              _hover={{ bg: 'rgba(0,0,0,0.03)', borderColor: 'brand.primary' }}
                            >
                              <Flex align="center" gap={2}>
                                <Badge colorScheme={typeColor(e.type)}>{typeLabel(e.type)}</Badge>
                                <Text fontSize="xs">
                                  {format(new Date(e.start_time), 'HH:mm')}
                                  {e.end_time && !isSameDay(new Date(e.start_time), new Date(e.end_time))
                                    ? ` – ${format(new Date(e.end_time), 'd.M.')}`
                                    : (e.end_time ? ` – ${format(new Date(e.end_time), 'HH:mm')}` : '')}
                                </Text>
                              </Flex>
                              <Text fontSize="sm" mt={1}>{e.title}</Text>
                            </Box>
                          ))}
                          {list.length > 3 && (
                            <Text fontSize="xs" color={subtleText}>+{list.length - 3} další…</Text>
                          )}
                        </Stack>
                      </Box>
                    );
                  })}
                </Grid>
              </Box>
            </>
          ) : (
            <Stack spacing={4}>
              {(() => {
                const keys = Array.from(byDate.keys()).sort();
                return keys.map((k) => {
                  const dayEvents = byDate.get(k) || [];
                  return (
                    <Box key={k} borderWidth="1px" borderColor={borderColor} borderRadius="md" overflow="hidden" bg={cardBg}>
                      <Box px={3} py={2} bg={listHeaderBg} borderLeftWidth="4px" borderLeftColor={'brand.primary'}>
                        <Flex align="center" gap={2}>
                          <Text fontWeight="semibold">
                            {format(new Date(k), 'EEEE d. M. yyyy', { locale: cs })}
                          </Text>
                          <Badge colorScheme="purple" borderRadius="full">{dayEvents.length}</Badge>
                        </Flex>
                      </Box>
                      <Stack spacing={3}>
                        {dayEvents.map((e) => (
                          <Flex
                            key={e.id}
                            as={RouterLink}
                            to={`/aktivita/${e.id}`}
                            align="center"
                            justify="space-between"
                            p={3}
                            borderWidth="1px"
                            borderColor={borderColor}
                            borderRadius="md"
                            bg={cardBg}
                            _hover={{ bg: hoverBg, borderColor: 'brand.primary' }}
                          >
                            <Flex direction="column" minW="200px">
                              <Text fontWeight="semibold">
                                {format(new Date(e.start_time), 'HH:mm')}
                                {e.end_time && !isSameDay(new Date(e.start_time), new Date(e.end_time))
                                  ? ` – ${format(new Date(e.end_time), 'd.M. HH:mm')}`
                                  : (e.end_time ? ` – ${format(new Date(e.end_time), 'HH:mm')}` : '')}
                              </Text>
                              {e.location && <Text color={mutedText} fontSize="sm">{e.location}</Text>}
                            </Flex>
                            <Flex align="center" gap={2} flex="1" justify="center">
                              <Badge colorScheme={typeColor(e.type)}>{typeLabel(e.type)}</Badge>
                              <Text>{e.title}</Text>
                            </Flex>
                          </Flex>
                        ))}
                      </Stack>
                    </Box>
                  );
                });
              })()}
            </Stack>
          )
        )}
      </Container>
    </MainLayout>
  );
};

export default ActivitiesCalendarPage;
