import React, { ReactNode, useContext, useEffect, useState } from "react"

const BANK_ACCOUNT_NUMBER_KEY = 'bank_account_number';
const BANK_ACCOUNT_HOLDER_KEY = 'bank_account_holder_name';
const HIDE_SOUPS_KEY = 'hide_soups';
const THEME_KEY = 'theme_preference';

export type ThemePreference = 'system' | 'light' | 'dark';

export type SettingsContextProps = {
  bankAccount?: string,
  holderName?: string,
  hideSoups?: boolean,
  themePreference: ThemePreference,
  setBankAccountNumber: (accountNumber?: string) => void,
  setBankAccountHolderName: (holderName?: string) => void,
  setHideSoupsOption: (hideSoups?: boolean) => void,
  setThemePreference: (theme: ThemePreference) => void,
}

type ContextProps = {
  children: ReactNode
}

const settingsContext = React.createContext<SettingsContextProps | null>(null);

export function ProvideSettings(props: Readonly<ContextProps>) {
  const settings = useProvideSettings();
  return <settingsContext.Provider value={settings}>{props.children}</settingsContext.Provider>
}

export const useSettings = () => {
  return useContext(settingsContext);
}

function getInitialTheme(): ThemePreference {
  try {
    const saved = localStorage.getItem(THEME_KEY) as ThemePreference | null;
    if (saved && ['system', 'light', 'dark'].includes(saved)) {
      return saved;
    }
  } catch (e) {
    // localStorage nedostupný
  }
  return 'system';
}

function useProvideSettings(): SettingsContextProps {
  const [bankAccount, setBankAccount] = useState<string | undefined>();
  const [holderName, setHolderName] = useState<string | undefined>();
  const [hideSoups, setHideSoups] = useState<boolean | undefined>();
  const [themePreference, setTheme] = useState<ThemePreference>(getInitialTheme);

  useEffect(() => {
    const accountNumber = localStorage.getItem(BANK_ACCOUNT_NUMBER_KEY);
    if (accountNumber) {
      setBankAccount(accountNumber);
    }
    const holderName = localStorage.getItem(BANK_ACCOUNT_HOLDER_KEY);
    if (holderName) {
      setHolderName(holderName);
    }
    const hideSoups = localStorage.getItem(HIDE_SOUPS_KEY);
    if (hideSoups !== null) {
      setHideSoups(hideSoups === 'true');
    }
  }, [])

  useEffect(() => {
    if (bankAccount) {
      localStorage.setItem(BANK_ACCOUNT_NUMBER_KEY, bankAccount)
    } else {
      localStorage.removeItem(BANK_ACCOUNT_NUMBER_KEY);
    }
  }, [bankAccount]);

  useEffect(() => {
    if (holderName) {
      localStorage.setItem(BANK_ACCOUNT_HOLDER_KEY, holderName);
    } else {
      localStorage.removeItem(BANK_ACCOUNT_HOLDER_KEY);
    }
  }, [holderName]);

  useEffect(() => {
    if (hideSoups) {
      localStorage.setItem(HIDE_SOUPS_KEY, hideSoups ? 'true' : 'false');
    } else {
      localStorage.removeItem(HIDE_SOUPS_KEY);
    }
  }, [hideSoups]);

  useEffect(() => {
    localStorage.setItem(THEME_KEY, themePreference);
  }, [themePreference]);

  useEffect(() => {
    const applyTheme = (theme: 'light' | 'dark') => {
      document.documentElement.setAttribute('data-bs-theme', theme);
    };

    if (themePreference === 'system') {
      const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
      applyTheme(mediaQuery.matches ? 'dark' : 'light');

      const handler = (e: MediaQueryListEvent) => {
        applyTheme(e.matches ? 'dark' : 'light');
      };
      mediaQuery.addEventListener('change', handler);
      return () => mediaQuery.removeEventListener('change', handler);
    } else {
      applyTheme(themePreference);
    }
  }, [themePreference]);

  function setBankAccountNumber(bankAccount?: string) {
    setBankAccount(bankAccount);
  }

  function setBankAccountHolderName(holderName?: string) {
    setHolderName(holderName);
  }

  function setHideSoupsOption(hideSoups?: boolean) {
    setHideSoups(hideSoups);
  }

  function setThemePreference(theme: ThemePreference) {
    setTheme(theme);
  }

  return {
    bankAccount,
    holderName,
    hideSoups,
    themePreference,
    setBankAccountNumber,
    setBankAccountHolderName,
    setHideSoupsOption,
    setThemePreference,
  }
}
