import { useCallback, useEffect, useMemo, useState } from 'react';
import { FlatList, Linking, RefreshControl, StyleSheet, View } from 'react-native';
import {
  ActivityIndicator, Appbar, Banner, Button, Card, FAB, IconButton, PaperProvider, SegmentedButtons, Switch, Text,
} from 'react-native-paper';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import { StatusBar } from 'expo-status-bar';
import { Calendar, LocaleConfig } from 'react-native-calendars';
import { Conference, loadConferences } from './src/api';
import { addToCalendar } from './src/calendar';
import { loadFavorites, saveFavorites } from './src/favorites';
import { isEnabled, setEnabled } from './src/notifications';
import { Logo } from './src/Logo';
import { SubmitForm } from './src/SubmitForm';
import { theme } from './src/theme';

LocaleConfig.locales.pl = {
  monthNames: ['styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień'],
  monthNamesShort: ['sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru'],
  dayNames: ['niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota'],
  dayNamesShort: ['ndz', 'pon', 'wt', 'śr', 'czw', 'pt', 'sob'],
  today: 'Dziś',
};
LocaleConfig.defaultLocale = 'pl';

type Tab = 'upcoming' | 'archive' | 'favorites';
const dayKey = (iso: string) => iso.slice(0, 10);

const MONTHS = ['sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru'];

function DateBadge({ iso }: { iso: string }) {
  const d = new Date(iso);
  return (
    <View style={s.badge}>
      <Text style={s.badgeDay}>{d.getDate()}</Text>
      <Text style={s.badgeMonth}>{MONTHS[d.getMonth()].toUpperCase()}</Text>
      <Text style={s.badgeYear}>{d.getFullYear()}</Text>
    </View>
  );
}

function Row({ icon, text }: { icon: keyof typeof MaterialCommunityIcons.glyphMap; text: string }) {
  return (
    <View style={s.meta}>
      <MaterialCommunityIcons name={icon} size={16} color={theme.colors.onSurfaceVariant} />
      <Text variant="bodyMedium" style={s.metaText}>{text}</Text>
    </View>
  );
}

function ConferenceCard({ c, fav, onFav }: { c: Conference; fav: boolean; onFav: () => void }) {
  return (
    <Card style={s.card} mode="elevated">
      <Card.Content style={s.cardRow}>
        <DateBadge iso={c.start} />
        <View style={s.cardBody}>
          <Text variant="titleMedium" style={s.title}>{c.title}</Text>
          {c.place && <Row icon="map-marker-outline" text={c.place} />}
          {c.organizer && <Row icon="domain" text={c.organizer} />}
        </View>
      </Card.Content>
      <Card.Actions>
        {c.url && <Button icon="open-in-new" onPress={() => Linking.openURL(c.url!)}>Strona</Button>}
        <Button icon="calendar-plus" onPress={() => addToCalendar(c).catch(() => {})}>Do kalendarza</Button>
        <IconButton
          icon={fav ? 'heart' : 'heart-outline'}
          iconColor={fav ? '#C62828' : theme.colors.onSurfaceVariant}
          accessibilityLabel={fav ? 'Usuń z ulubionych' : 'Dodaj do ulubionych'}
          onPress={onFav}
        />
      </Card.Actions>
    </Card>
  );
}

export default function App() {
  const [items, setItems] = useState<Conference[]>([]);
  const [offline, setOffline] = useState(false);
  const [loading, setLoading] = useState(true);
  const [tab, setTab] = useState<Tab>('upcoming');
  const [asc, setAsc] = useState(true);
  const [calView, setCalView] = useState(false);
  const [day, setDay] = useState<string | null>(null);
  const [month, setMonth] = useState<string | null>(null);
  const [favs, setFavs] = useState<string[]>([]);
  const [notify, setNotify] = useState(false);
  const [formOpen, setFormOpen] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    const r = await loadConferences();
    setItems(r.items);
    setOffline(r.offline);
    setLoading(false);
  }, []);

  useEffect(() => {
    isEnabled().then(setNotify).catch(() => {});
    loadFavorites().then(setFavs);
    load();
  }, [load]);

  const toggleFav = (id: string) => {
    const next = favs.includes(id) ? favs.filter((x) => x !== id) : [...favs, id];
    setFavs(next);
    saveFavorites(next).catch(() => {});
  };

  const isPast = (c: Conference) => new Date(c.end ?? c.start).getTime() < Date.now() - 864e5;

  // The calendar opens on the month of the next conference, not on an empty current month.
  const firstMonth = useMemo(() => {
    const next = [...items].sort((a, b) => a.start.localeCompare(b.start)).find((c) => !isPast(c));
    return (next ?? items[0])?.start.slice(0, 7) ?? new Date().toISOString().slice(0, 7);
  }, [items]);

  const shown = useMemo(() => {
    let list = items;
    if (calView) {
      list = day
        ? items.filter((c) => dayKey(c.start) === day)
        : items.filter((c) => c.start.slice(0, 7) === (month ?? firstMonth));
    }
    else if (tab === 'upcoming') list = items.filter((c) => !isPast(c));
    else if (tab === 'archive') list = items.filter(isPast);
    else list = items.filter((c) => favs.includes(c.id));
    const sorted = [...list].sort((a, b) => a.start.localeCompare(b.start));
    return asc ? sorted : sorted.reverse();
  }, [items, tab, asc, calView, day, month, favs]);

  const marked = useMemo(() => {
    const m: Record<string, any> = {};
    for (const c of items) m[dayKey(c.start)] = { marked: true, dotColor: theme.colors.secondary };
    if (day) m[day] = { ...(m[day] ?? {}), selected: true, selectedColor: theme.colors.primary };
    return m;
  }, [items, day]);

  return (
    <SafeAreaProvider>
      <PaperProvider theme={theme}>
        <StatusBar style="light" />
        <SafeAreaView style={s.root} edges={['top']}>
          <Appbar.Header style={s.header}>
            <Appbar.Action icon={calView ? 'format-list-bulleted' : 'calendar-month'} color="#FFFFFF" onPress={() => setCalView(!calView)} accessibilityLabel="Przełącz widok listy i kalendarza" />
            <View style={s.brand}>
              <Logo size={38} />
              <View>
                <Text style={s.brandName}>konferencja<Text style={s.brandAccent}>podatkowa</Text>.pl</Text>
                <Text style={s.brandTag}>Niekomercyjne konferencje podatkowe</Text>
              </View>
            </View>
            <Appbar.Action icon={asc ? 'sort-calendar-ascending' : 'sort-calendar-descending'} color="#FFFFFF" onPress={() => setAsc(!asc)} accessibilityLabel="Zmień kolejność sortowania po dacie" />
          </Appbar.Header>
          <Banner visible={offline} icon="wifi-off">
            Brak połączenia. Pokazuję ostatnio zapisane dane.
          </Banner>
          <FlatList
            data={shown}
            keyExtractor={(c) => c.id}
            style={s.listBg}
            contentContainerStyle={s.list}
            refreshControl={<RefreshControl refreshing={loading && items.length > 0} onRefresh={load} />}
            ListHeaderComponent={
              <View>
                <View style={s.notifyCard}>
                  <MaterialCommunityIcons name="bell-outline" size={22} color={theme.colors.primary} />
                  <View style={s.notifyText}>
                    <Text variant="titleSmall">Powiadomienia</Text>
                    <Text variant="bodySmall">Daj znać o każdej nowej konferencji</Text>
                  </View>
                  <Switch
                    value={notify}
                    onValueChange={(v) => setEnabled(v).then(setNotify).catch(() => setNotify(false))}
                  />
                </View>
                {calView ? (
                  <View style={s.calWrap}>
                    <Calendar firstDay={1} markedDates={marked} current={`${month ?? firstMonth}-01`}
                      onDayPress={(d) => setDay(day === d.dateString ? null : d.dateString)}
                      onMonthChange={(m) => { setMonth(`${m.year}-${String(m.month).padStart(2, '0')}`); setDay(null); }}
                      theme={{ todayTextColor: theme.colors.primary, arrowColor: theme.colors.primary }} />
                  </View>
                ) : (
                  <SegmentedButtons
                    style={s.chips}
                    value={tab}
                    onValueChange={(v) => setTab(v as Tab)}
                    buttons={[
                      { value: 'upcoming', label: 'Wkrótce', showSelectedCheck: false, labelStyle: s.segLabel },
                      { value: 'archive', label: 'Archiwum', showSelectedCheck: false, labelStyle: s.segLabel },
                      { value: 'favorites', label: 'Ulubione', showSelectedCheck: false, labelStyle: s.segLabel },
                    ]}
                  />
                )}
              </View>
            }
            ListEmptyComponent={
              loading ? <ActivityIndicator style={s.empty} /> : (
                <Text style={s.empty} variant="bodyMedium">
                  {calView ? 'Brak konferencji w tym miesiącu.' : tab === 'favorites' ? 'Nie masz jeszcze ulubionych. Dotknij serca przy konferencji.' : 'Brak konferencji do wyświetlenia.'}
                </Text>
              )
            }
            renderItem={({ item }) => <ConferenceCard c={item} fav={favs.includes(item.id)} onFav={() => toggleFav(item.id)} />}
          />
          <FAB
            icon="email-edit-outline"
            label="Zgłoś konferencję"
            style={s.fab}
            color="#FFFFFF"
            onPress={() => setFormOpen(true)}
          />
        </SafeAreaView>
        <SubmitForm visible={formOpen} onClose={() => setFormOpen(false)} />
      </PaperProvider>
    </SafeAreaProvider>
  );
}

const s = StyleSheet.create({
  root: { flex: 1, backgroundColor: theme.colors.primary },
  header: { backgroundColor: theme.colors.primary },
  brand: { flex: 1, flexDirection: 'row', alignItems: 'center', gap: 10 },
  brandName: { color: '#FFFFFF', fontWeight: '700', fontSize: 17 },
  brandAccent: { color: '#F2D27A' },
  brandTag: { color: '#C9D8E4', fontSize: 11 },
  listBg: { backgroundColor: theme.colors.background },
  list: { padding: 16, paddingBottom: 96, backgroundColor: theme.colors.background },
  notifyCard: {
    flexDirection: 'row', alignItems: 'center', gap: 12, padding: 14, marginBottom: 12,
    backgroundColor: theme.colors.primaryContainer, borderRadius: 12,
  },
  notifyText: { flex: 1 },
  chips: { marginBottom: 12 },
  segLabel: { fontSize: 13, marginHorizontal: 4 },
  calWrap: { marginBottom: 12, borderRadius: 12, overflow: 'hidden' },
  card: { marginBottom: 12, backgroundColor: theme.colors.surface },
  cardRow: { flexDirection: 'row', gap: 14 },
  cardBody: { flex: 1, gap: 4 },
  title: { fontWeight: '700', color: theme.colors.primary },
  meta: { flexDirection: 'row', alignItems: 'center', gap: 6 },
  metaText: { flex: 1, color: theme.colors.onSurfaceVariant },
  badge: {
    width: 62, alignItems: 'center', justifyContent: 'center', paddingVertical: 8,
    backgroundColor: theme.colors.secondaryContainer, borderRadius: 10,
  },
  badgeDay: { fontSize: 24, fontWeight: '800', color: theme.colors.onSecondaryContainer, lineHeight: 28 },
  badgeMonth: { fontSize: 12, fontWeight: '700', color: theme.colors.onSecondaryContainer },
  badgeYear: { fontSize: 11, color: theme.colors.onSecondaryContainer },
  empty: { marginTop: 40, textAlign: 'center' },
  fab: { position: 'absolute', right: 16, bottom: 24, backgroundColor: theme.colors.primary },
});
