import React, { useState, useCallback } from 'react';
import { View, Text, StyleSheet, SafeAreaView, ScrollView, Switch, TouchableOpacity, Alert, Linking, Modal, Pressable, BackHandler } from 'react-native';
import { useFocusEffect, useRouter } from 'expo-router';
import { Header } from '@/components/Header';
import { ListItem } from '@/components/ListItem';
import { OptionPickerModal } from '@/components/OptionPickerModal';
import { CategoryEditorModal } from '@/components/CategoryEditorModal';
import { SyncModal } from '@/components/SyncModal';
import { FriendsModal } from '@/components/FriendsModal';
import { LegalModal } from '@/components/LegalModal';
import { ServerUrlModal } from '@/components/ServerUrlModal';
import SyncStatus from '@/components/SyncStatus';
import { useSettings, SORT_OPTIONS, REMINDER_OPTIONS, ACCENT_PRESETS, DEFAULT_ACCENT } from '@/theme';
import { useCategories } from '@/hooks/useDatabase';
import { getAuthUser, getAuthToken } from '@/services/auth';
import { checkForUpdates, getCurrentAppVersion } from '@/services/updates';
import { getLastSyncTime } from '@/database/sync';
import Category from '@/models/Category';
import Svg, { Path } from 'react-native-svg';
import ColorWheel from '@/components/ColorWheel';
import { getLastVisitedTab, tabHref } from '@/utils/tabHistory';

export default function SettingsScreen() {
  const router = useRouter();
  const { theme, notifications, setNotifications, defaultCategoryId, setDefaultCategoryId, sortBy, setSortBy, reminderPreference, setReminderPreference, apiUrl, accentColor, setAccentColor, todoAheadDays, setTodoAheadDays, showCompleted, setShowCompleted } = useSettings();
  const categories = useCategories();
  const [picker, setPicker] = useState<null | 'category' | 'sort' | 'reminder' | 'todoAhead'>(null);
  const [editingCategory, setEditingCategory] = useState<Category | null | 'new'>(null);
  const [syncVisible, setSyncVisible] = useState(false);
  const [friendsVisible, setFriendsVisible] = useState(false);
  const [legalVisible, setLegalVisible] = useState<null | 'privacy' | 'terms'>(null);
  const [serverUrlVisible, setServerUrlVisible] = useState(false);
  const [customAccentVisible, setCustomAccentVisible] = useState(false);
  const [draftAccent, setDraftAccent] = useState(accentColor);
  const [syncSubtitle, setSyncSubtitle] = useState('Checking...');
  const [updateSubtitle, setUpdateSubtitle] = useState('Tap to check');

  const handleCheckUpdates = async () => {
    setUpdateSubtitle('Checking...');
    const update = await checkForUpdates();
    if (!update) {
      setUpdateSubtitle('Up to date');
      Alert.alert('Up to date', `You're running the latest version (${getCurrentAppVersion()}).`);
      return;
    }
    setUpdateSubtitle(`${update.version} available`);
    const url = update.apkUrl ?? update.releaseUrl;
    Alert.alert('Update available', `Version ${update.version} is available for download.`, [
      { text: 'Later', style: 'cancel' },
      {
        text: 'Download',
        onPress: () => {
          if (url) Linking.openURL(url).catch(() => {});
        },
      },
    ]);
  };

  const refreshSyncStatus = async () => {
    const token = await getAuthToken();
    if (!token) {
      setSyncSubtitle('Not signed in');
      return;
    }
    const user = await getAuthUser();
    const lastSync = await getLastSyncTime();
    if (user) {
      setSyncSubtitle(
        lastSync ? `Signed in · synced ${formatSyncTime(lastSync)}` : `Signed in as ${user.username}`
      );
    } else {
      setSyncSubtitle('Not signed in');
    }
  };

  React.useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    refreshSyncStatus();
  }, []);

  useFocusEffect(
    useCallback(() => {
      const sub = BackHandler.addEventListener('hardwareBackPress', () => {
        const target = getLastVisitedTab();
        if (target && target !== 'settings') {
          router.navigate(tabHref(target));
        }
        return true;
      });
      return () => sub.remove();
    }, [router])
  );

  const defaultCategory = categories.find((c) => c.id === defaultCategoryId);
  const defaultCategoryLabel = defaultCategory?.name ?? 'None';
  const reminderLabel = REMINDER_OPTIONS.find((o) => o.value === reminderPreference)?.label ?? 'No reminder';

  const openCustomAccent = () => {
    setDraftAccent(accentColor);
    setCustomAccentVisible(true);
  };

  const handleDefaultCategory = (value: string | string[]) => {
    setDefaultCategoryId(Array.isArray(value) ? value[0] : value);
  };

  const handleReminderPreference = (value: string | string[]) => {
    setReminderPreference((Array.isArray(value) ? value[0] : value) as typeof reminderPreference);
  };

  const handleTodoAheadDays = (value: string | string[]) => {
    setTodoAheadDays(parseInt(Array.isArray(value) ? value[0] : value, 10));
  };

  const editorVisible = editingCategory !== null;
  const editorCategory = editingCategory === 'new' ? null : editingCategory;

  return (
    <SafeAreaView style={[styles.container, { backgroundColor: theme.background }]}>
      <Header title="Settings" showLogo={false} />
      <ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false}>
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>Categories</Text>
        {categories.map((category) => (
          <ListItem
            key={category.id}
            title={category.name}
            subtitle={category.id === defaultCategoryId ? 'Default category' : undefined}
            leftElement={
              <View style={[styles.categoryDot, { backgroundColor: category.color }]} />
            }
            onPress={() => setEditingCategory(category)}
            showChevron
          />
        ))}
        <TouchableOpacity
          style={[styles.addCategoryRow, { borderColor: theme.borderStrong }]}
          onPress={() => setEditingCategory('new')}
          activeOpacity={0.7}
        >
          <View style={[styles.addIcon, { backgroundColor: theme.accentSoft }]}>
            <Svg width={16} height={16} viewBox="0 0 24 24">
              <Path d="M12 5v14M5 12h14" stroke={theme.accentText} strokeWidth={2} strokeLinecap="round" />
            </Svg>
          </View>
          <Text style={[styles.addCategoryText, { color: theme.accent }]}>Add Category</Text>
        </TouchableOpacity>
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>Notifications</Text>
        <ListItem
          title="Push Notifications"
          subtitle="Receive task reminders"
          rightElement={
            <Switch
              value={notifications}
              onValueChange={setNotifications}
              thumbColor="#FFFFFF"
              trackColor={{ false: theme.borderStrong, true: theme.accent }}
            />
          }
        />
        <ListItem
          title="Reminder Preferences"
          subtitle={notifications ? reminderLabel : 'Enable notifications first'}
          onPress={() => notifications && setPicker('reminder')}
          showChevron
        />
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>Tasks</Text>
        <ListItem
          title="Default Category"
          subtitle={defaultCategoryLabel}
          onPress={() => setPicker('category')}
          showChevron
        />
        <ListItem
          title="Sort Tasks By"
          subtitle={SORT_OPTIONS.find((o) => o.value === sortBy)?.label ?? 'Date'}
          onPress={() => setPicker('sort')}
          showChevron
        />
        <ListItem
          title="Show Completed Tasks"
          subtitle="Hide or show finished tasks in the Todo list"
          rightElement={
            <Switch
              value={showCompleted}
              onValueChange={setShowCompleted}
              thumbColor="#FFFFFF"
              trackColor={{ false: theme.borderStrong, true: theme.accent }}
            />
          }
        />
        <ListItem
          title="Show Calendar Tasks"
          subtitle={todoAheadDays === 0 ? 'Only today' : `Up to ${todoAheadDays} days ahead`}
          onPress={() => setPicker('todoAhead')}
          showChevron
        />
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>Appearance</Text>
        <Text style={[styles.sectionHint, { color: theme.textFaint }]}>Accent color</Text>
        <View style={styles.accentPresets}>
          {ACCENT_PRESETS.map((c) => (
            <TouchableOpacity
              key={c}
              style={[
                styles.accentSwatch,
                { backgroundColor: c },
                accentColor.toUpperCase() === c && styles.accentSwatchSelected,
              ]}
              onPress={() => setAccentColor(c)}
              activeOpacity={0.8}
            >
              {accentColor.toUpperCase() === c && (
                <Svg width={16} height={16} viewBox="0 0 24 24">
                  <Path d="M5 12l5 5 9-10" stroke={contrastOnSwatch(c)} strokeWidth={3} strokeLinecap="round" strokeLinejoin="round" fill="none" />
                </Svg>
              )}
            </TouchableOpacity>
          ))}
        </View>
        <ListItem
          title="Custom Color"
          subtitle={accentColor}
          leftElement={<View style={[styles.categoryDot, { backgroundColor: accentColor }]} />}
          onPress={openCustomAccent}
          showChevron
        />
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>Data</Text>
        <SyncStatus />
        <ListItem
          title="Backup & Sync"
          subtitle={syncSubtitle}
          onPress={() => setSyncVisible(true)}
          showChevron
        />
        <ListItem
          title="Friends"
          subtitle="Manage friends and requests"
          onPress={() => setFriendsVisible(true)}
          showChevron
        />
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>Server</Text>
        <ListItem
          title="Backend URL"
          subtitle={apiUrl}
          onPress={() => setServerUrlVisible(true)}
          showChevron
        />
        <Text style={[styles.sectionTitle, { color: theme.textMuted }]}>About</Text>
        <ListItem
          title="Check for Updates"
          subtitle={updateSubtitle}
          onPress={handleCheckUpdates}
          showChevron
        />
        <ListItem
          title="Version"
          subtitle={getCurrentAppVersion()}
        />
        <ListItem
          title="Privacy Policy"
          onPress={() => setLegalVisible('privacy')}
          showChevron
        />
        <ListItem
          title="Terms of Service"
          onPress={() => setLegalVisible('terms')}
          showChevron
        />
      </ScrollView>

      <OptionPickerModal
        visible={picker === 'category'}
        title="Default Category"
        options={[{ value: '', label: 'None', color: '#9E9E9E' }, ...categories.map((c) => ({ value: c.id, label: c.name, color: c.color }))]}
        selectedValue={defaultCategoryId}
        onSelect={handleDefaultCategory}
        onClose={() => setPicker(null)}
      />

      <OptionPickerModal
        visible={picker === 'sort'}
        title="Sort Tasks By"
        options={SORT_OPTIONS}
        selectedValue={sortBy}
        onSelect={(value) => setSortBy(value as typeof sortBy)}
        onClose={() => setPicker(null)}
      />

      <OptionPickerModal
        visible={picker === 'reminder'}
        title="Reminder Preferences"
        options={REMINDER_OPTIONS}
        selectedValue={reminderPreference}
        onSelect={handleReminderPreference}
        onClose={() => setPicker(null)}
      />

      <OptionPickerModal
        visible={picker === 'todoAhead'}
        title="Calendar Tasks in Todo"
        options={AHEAD_OPTIONS}
        selectedValue={String(todoAheadDays)}
        onSelect={handleTodoAheadDays}
        onClose={() => setPicker(null)}
      />

      <CategoryEditorModal
        visible={editorVisible}
        category={editorCategory}
        categoryCount={categories.length}
        onClose={() => setEditingCategory(null)}
      />

      <SyncModal visible={syncVisible} onClose={() => { setSyncVisible(false); refreshSyncStatus(); }} />

      <FriendsModal visible={friendsVisible} onClose={() => setFriendsVisible(false)} />

      <ServerUrlModal visible={serverUrlVisible} onClose={() => setServerUrlVisible(false)} />

      <Modal visible={customAccentVisible} transparent animationType="fade" onRequestClose={() => setCustomAccentVisible(false)}>
        <Pressable
          style={styles.accentModalOverlay}
          onPress={() => setCustomAccentVisible(false)}
        >
          <Pressable style={[styles.accentModalSheet, { backgroundColor: theme.sheetBg }]} onPress={() => {}}>
            <View style={styles.accentModalHeader}>
              <Text style={[styles.accentModalTitle, { color: theme.text }]}>Custom Accent Color</Text>
              <TouchableOpacity onPress={() => setCustomAccentVisible(false)} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}>
                <Svg width={18} height={18} viewBox="0 0 24 24">
                  <Path d="M18 6L6 18M6 6l12 12" stroke={theme.textSecondary} strokeWidth={2.2} strokeLinecap="round" />
                </Svg>
              </TouchableOpacity>
            </View>
            <ColorWheel color={draftAccent} onChange={setDraftAccent} />
            <View style={styles.accentModalActions}>
              <TouchableOpacity
                style={[styles.accentModalButton, { borderColor: theme.borderStrong }]}
                onPress={() => { setDraftAccent(DEFAULT_ACCENT); setAccentColor(DEFAULT_ACCENT); }}
                activeOpacity={0.7}
              >
                <Text style={[styles.accentModalButtonText, { color: theme.textSecondary }]}>Reset</Text>
              </TouchableOpacity>
              <TouchableOpacity
                style={[styles.accentModalButton, styles.accentModalButtonPrimary, { backgroundColor: theme.accent }]}
                onPress={() => { setAccentColor(draftAccent); setCustomAccentVisible(false); }}
                activeOpacity={0.8}
              >
                <Text style={[styles.accentModalButtonText, { color: theme.accentText }]}>Apply</Text>
              </TouchableOpacity>
            </View>
          </Pressable>
        </Pressable>
      </Modal>

      <LegalModal
        visible={legalVisible !== null}
        type={legalVisible}
        onClose={() => setLegalVisible(null)}
      />
    </SafeAreaView>
  );
}

const AHEAD_OPTIONS: { value: string; label: string }[] = Array.from({ length: 29 }, (_, i) => ({
  value: String(i),
  label: i === 0 ? 'Only today' : `${i} day${i === 1 ? '' : 's'}`,
}));

function formatSyncTime(timestamp: number): string {
  const seconds = Math.floor((Date.now() - timestamp) / 1000);
  if (seconds < 60) return 'just now';
  if (seconds < 3600) return `${Math.floor(seconds / 60)} min ago`;
  if (seconds < 86400) return `${Math.floor(seconds / 3600)} h ago`;
  return new Date(timestamp).toLocaleDateString();
}

function contrastOnSwatch(hex: string): string {
  const h = hex.replace(/^#/, '');
  const r = parseInt(h.slice(0, 2), 16) / 255;
  const g = parseInt(h.slice(2, 4), 16) / 255;
  const b = parseInt(h.slice(4, 6), 16) / 255;
  const linear = (v: number) => (v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4));
  const luminance = 0.2126 * linear(r) + 0.7152 * linear(g) + 0.0722 * linear(b);
  return luminance > 0.5 ? '#111111' : '#FFFFFF';
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  content: {
    flexGrow: 1,
    paddingHorizontal: 16,
    paddingTop: 8,
  },
  sectionTitle: {
    fontSize: 13,
    fontWeight: '600',
    textTransform: 'uppercase',
    letterSpacing: 0.5,
    marginTop: 24,
    marginBottom: 8,
    marginLeft: 4,
  },
  categoryDot: {
    width: 20,
    height: 20,
    borderRadius: 10,
  },
  addCategoryRow: {
    flexDirection: 'row',
    alignItems: 'center',
    gap: 10,
    paddingVertical: 12,
    paddingHorizontal: 16,
    borderRadius: 12,
    borderWidth: 1,
    borderStyle: 'dashed',
    marginBottom: 8,
  },
  addIcon: {
    width: 28,
    height: 28,
    borderRadius: 14,
    alignItems: 'center',
    justifyContent: 'center',
  },
  addCategoryText: {
    fontSize: 15,
    fontWeight: '600',
  },
  sectionHint: {
    fontSize: 12,
    marginLeft: 4,
    marginBottom: 8,
  },
  accentPresets: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    gap: 10,
    paddingHorizontal: 4,
    marginBottom: 4,
  },
  accentSwatch: {
    width: 36,
    height: 36,
    borderRadius: 18,
    alignItems: 'center',
    justifyContent: 'center',
  },
  accentSwatchSelected: {
    borderWidth: 2,
    borderColor: '#FFFFFF',
    shadowColor: '#000',
    shadowOpacity: 0.3,
    shadowRadius: 3,
    elevation: 3,
  },
  accentModalOverlay: {
    flex: 1,
    backgroundColor: 'rgba(0,0,0,0.6)',
    alignItems: 'center',
    justifyContent: 'center',
    padding: 24,
  },
  accentModalSheet: {
    width: '100%',
    maxWidth: 400,
    borderRadius: 16,
    padding: 20,
  },
  accentModalHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: 16,
  },
  accentModalTitle: {
    fontSize: 18,
    fontWeight: '700',
  },
  accentModalActions: {
    flexDirection: 'row',
    gap: 12,
    marginTop: 16,
  },
  accentModalButton: {
    flex: 1,
    paddingVertical: 12,
    borderRadius: 12,
    borderWidth: 1,
    alignItems: 'center',
  },
  accentModalButtonPrimary: {
    borderWidth: 0,
  },
  accentModalButtonText: {
    fontSize: 15,
    fontWeight: '600',
  },
});
