import React, { createContext, useCallback, useContext, useEffect, useMemo, useState, ReactNode } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { DEFAULT_API_BASE_URL, API_URL_KEY } from '@/services/auth';

export type SortBy = 'date' | 'priority' | 'alpha' | 'created';

export const SORT_OPTIONS: { value: SortBy; label: string }[] = [
  { value: 'date', label: 'Date' },
  { value: 'priority', label: 'Priority' },
  { value: 'alpha', label: 'Alphabetically' },
  { value: 'created', label: 'Creation Date' },
];

export type ReminderPreference = 'none' | 'atTime' | '5m' | '15m' | '30m' | '1h' | '1d';

export const REMINDER_OPTIONS: { value: ReminderPreference; label: string }[] = [
  { value: 'none', label: 'No reminder' },
  { value: 'atTime', label: 'At due time' },
  { value: '5m', label: '5 minutes before' },
  { value: '15m', label: '15 minutes before' },
  { value: '30m', label: '30 minutes before' },
  { value: '1h', label: '1 hour before' },
  { value: '1d', label: '1 day before' },
];

export interface ThemeColors {
  background: string;
  card: string;
  cardAlt: string;
  border: string;
  borderStrong: string;
  text: string;
  textSecondary: string;
  textFaint: string;
  textMuted: string;
  accent: string;
  accentStrong: string;
  accentSoft: string;
  accentBorder: string;
  accentText: string;
  inputBg: string;
  overlay: string;
  sheetBg: string;
  tabBarBg: string;
}

export const DEFAULT_ACCENT = '#EF5350';

export const ACCENT_PRESETS: string[] = [
  '#EF5350',
  '#E91E63',
  '#AB47BC',
  '#7E57C2',
  '#5C6BC0',
  '#29B6F6',
  '#26A69A',
  '#66BB6A',
  '#FFCA28',
  '#FF7043',
  '#8D6E63',
];

function parseHex(hex: string): [number, number, number] {
  const h = hex.replace(/^#/, '');
  return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)];
}

function toHexByte(n: number): string {
  return Math.max(0, Math.min(255, Math.round(n))).toString(16).padStart(2, '0');
}

export function mixHex(color: string, target: string, ratio: number): string {
  const [r1, g1, b1] = parseHex(color);
  const [r2, g2, b2] = parseHex(target);
  return `#${toHexByte(r1 + (r2 - r1) * ratio)}${toHexByte(g1 + (g2 - g1) * ratio)}${toHexByte(b1 + (b2 - b1) * ratio)}`.toUpperCase();
}

export function desaturate(hex: string, amount: number): string {
  const [r, g, b] = parseHex(hex);
  const gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;
  const shift = 1 - amount;
  return `#${toHexByte(gray + (r - gray) * shift)}${toHexByte(gray + (g - gray) * shift)}${toHexByte(gray + (b - gray) * shift)}`.toUpperCase();
}

function accentTextColor(accent: string): string {
  const [r, g, b] = parseHex(accent).map((v) => v / 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';
}

export function colors(accent: string = DEFAULT_ACCENT): ThemeColors {
  const softAccent = desaturate(accent, 0.35);
  return {
    background: '#121212',
    card: '#1E1E1E',
    cardAlt: '#28292C',
    border: '#2C2E33',
    borderStrong: '#3C3E45',
    text: '#F2F3F5',
    textSecondary: '#E3E4E8',
    textFaint: '#C4C6CC',
    textMuted: '#9C9FA7',
    accent,
    accentStrong: mixHex(accent, '#FFFFFF', 0.55),
    accentSoft: mixHex(softAccent, '#121212', 0.18),
    accentBorder: mixHex(desaturate(accent, 0.15), '#121212', 0.5),
    accentText: accentTextColor(accent),
    inputBg: '#1A1B1E',
    overlay: 'rgba(0,0,0,0.6)',
    sheetBg: '#26282D',
    tabBarBg: '#16171A',
  };
}

interface SettingsContextType {
  notifications: boolean;
  setNotifications: (value: boolean) => void;
  defaultCategoryId: string;
  setDefaultCategoryId: (value: string) => void;
  sortBy: SortBy;
  setSortBy: (value: SortBy) => void;
  reminderPreference: ReminderPreference;
  setReminderPreference: (value: ReminderPreference) => void;
  apiUrl: string;
  setApiUrl: (value: string) => void;
  accentColor: string;
  setAccentColor: (value: string) => void;
  todoAheadDays: number;
  setTodoAheadDays: (value: number) => void;
  showCompleted: boolean;
  setShowCompleted: (value: boolean) => void;
  theme: ThemeColors;
}

export const DEFAULT_TODO_AHEAD_DAYS = 7;

const STORAGE_KEYS = {
  notifications: 'settings:notifications',
  defaultCategoryId: 'settings:defaultCategoryId',
  sortBy: 'settings:sortBy',
  reminderPreference: 'settings:reminderPreference',
  accentColor: 'settings:accentColor',
  todoAheadDays: 'settings:todoAheadDays',
  showCompleted: 'settings:showCompleted',
};

const SettingsContext = createContext<SettingsContextType | null>(null);

function useStoredSetting<T>(key: string, initialValue: T): [T, (value: T) => void, boolean] {
  const [value, setValue] = useState<T>(initialValue);
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    AsyncStorage.getItem(key)
      .then((stored) => {
        if (stored !== null) {
          setValue(JSON.parse(stored) as T);
        }
      })
      .catch(() => {})
      .finally(() => setLoaded(true));
  }, [key]);

  const update = useCallback(
    (next: T) => {
      setValue(next);
      AsyncStorage.setItem(key, JSON.stringify(next)).catch(() => {});
    },
    [key]
  );

  return [value, update, loaded];
}

export function SettingsProvider({ children }: { children: ReactNode }) {
  const [notifications, setNotifications] = useStoredSetting<boolean>(STORAGE_KEYS.notifications, true);
  const [defaultCategoryId, setDefaultCategoryId] = useStoredSetting<string>(STORAGE_KEYS.defaultCategoryId, '');
  const [sortBy, setSortBy] = useStoredSetting<SortBy>(STORAGE_KEYS.sortBy, 'date');
  const [reminderPreference, setReminderPreference] = useStoredSetting<ReminderPreference>(
    STORAGE_KEYS.reminderPreference,
    '15m',
  );
  const [apiUrl, setApiUrl] = useStoredSetting<string>(API_URL_KEY, DEFAULT_API_BASE_URL);
  const [accentColor, setAccentColor] = useStoredSetting<string>(STORAGE_KEYS.accentColor, DEFAULT_ACCENT);
  const [todoAheadDays, setTodoAheadDays] = useStoredSetting<number>(STORAGE_KEYS.todoAheadDays, DEFAULT_TODO_AHEAD_DAYS);
  const [showCompleted, setShowCompleted] = useStoredSetting<boolean>(STORAGE_KEYS.showCompleted, false);

  const theme = useMemo(() => colors(accentColor), [accentColor]);

  const value = useMemo<SettingsContextType>(
    () => ({
      notifications,
      setNotifications,
      defaultCategoryId,
      setDefaultCategoryId,
      sortBy,
      setSortBy,
      reminderPreference,
      setReminderPreference,
      apiUrl,
      setApiUrl,
      accentColor,
      setAccentColor,
      todoAheadDays,
      setTodoAheadDays,
      showCompleted,
      setShowCompleted,
      theme,
    }),
    [
      notifications,
      setNotifications,
      defaultCategoryId,
      setDefaultCategoryId,
      sortBy,
      setSortBy,
      reminderPreference,
      setReminderPreference,
      apiUrl,
      setApiUrl,
      accentColor,
      setAccentColor,
      todoAheadDays,
      setTodoAheadDays,
      showCompleted,
      setShowCompleted,
      theme,
    ]
  );

  return (
    <SettingsContext.Provider value={value}>
      {children}
    </SettingsContext.Provider>
  );
}

export function useSettings() {
  const context = useContext(SettingsContext);
  if (!context) {
    throw new Error('useSettings must be used within a SettingsProvider');
  }
  return context;
}

export * from './theme/tokens';
