import { useEffect, useState } from "react";
import { Navbar, Nav, NavDropdown, Modal, Button } from "react-bootstrap";
import { useAuth } from "../context/auth";
import SettingsModal from "./modals/SettingsModal";
import { useSettings, ThemePreference } from "../context/settings";
import HuePicker from "./HuePicker";
import PizzaCalculatorModal from "./modals/PizzaCalculatorModal";
import RefreshMenuModal from "./modals/RefreshMenuModal";
import GenerateQrModal from "./modals/GenerateQrModal";
import GenerateMockDataModal from "./modals/GenerateMockDataModal";
import ClearMockDataModal from "./modals/ClearMockDataModal";
import { useNavigate } from "react-router";
import { STATS_URL, OBJEDNANI_URL, NAVRHY_URL } from "../AppRoutes";
import { LunchChoices, getChangelogs } from "../../../types";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faSun, faMoon } from "@fortawesome/free-solid-svg-icons";
import { formatDateString } from "../Utils";

const LAST_SEEN_CHANGELOG_KEY = "lastChangelogDate";

const IS_DEV = process.env.NODE_ENV === 'development';

type Props = {
    choices?: LunchChoices;
    dayIndex?: number;
};

export default function Header({ choices, dayIndex }: Props) {
    const auth = useAuth();
    const settings = useSettings();
    const navigate = useNavigate();
    const [settingsModalOpen, setSettingsModalOpen] = useState<boolean>(false);
    const [pizzaModalOpen, setPizzaModalOpen] = useState<boolean>(false);
    const [refreshMenuModalOpen, setRefreshMenuModalOpen] = useState<boolean>(false);
    const [changelogModalOpen, setChangelogModalOpen] = useState<boolean>(false);
    const [changelogEntries, setChangelogEntries] = useState<Record<string, string[]>>({});
    const [qrModalOpen, setQrModalOpen] = useState<boolean>(false);
    const [generateMockModalOpen, setGenerateMockModalOpen] = useState<boolean>(false);
    const [clearMockModalOpen, setClearMockModalOpen] = useState<boolean>(false);

    const effectiveDark = settings?.effectiveDark ?? false;

    useEffect(() => {
        if (!auth?.login) return;
        const lastSeen = localStorage.getItem(LAST_SEEN_CHANGELOG_KEY) ?? undefined;
        getChangelogs({ query: lastSeen ? { since: lastSeen } : {} }).then(response => {
            const entries = response.data;
            if (!entries || Object.keys(entries).length === 0) return;
            setChangelogEntries(entries);
            setChangelogModalOpen(true);
            const newestDate = Object.keys(entries).sort((a, b) => b.localeCompare(a))[0];
            localStorage.setItem(LAST_SEEN_CHANGELOG_KEY, newestDate);
        });
    }, [auth?.login]);

    const closeSettingsModal = () => {
        setSettingsModalOpen(false);
    }

    const closePizzaModal = () => {
        setPizzaModalOpen(false);
    }

    const closeRefreshMenuModal = () => {
        setRefreshMenuModalOpen(false);
    }

    const closeQrModal = () => {
        setQrModalOpen(false);
    }

    const handleQrMenuClick = () => {
        if (!settings?.bankAccount || !settings?.holderName) {
            alert('Pro generování QR kódů je nutné mít v nastavení vyplněné číslo účtu a jméno držitele účtu.');
            return;
        }
        setQrModalOpen(true);
    }

    const toggleTheme = () => {
        const newTheme: ThemePreference = effectiveDark ? 'light' : 'dark';
        settings?.setThemePreference(newTheme);
    }

    const isValidInteger = (str: string) => {
        str = str.trim();
        if (!str) {
            return false;
        }
        str = str.replace(/^0+/, "") || "0";
        const n = Math.floor(Number(str));
        return n !== Infinity && String(n) === str && n >= 0;
    }

    const saveSettings = (bankAccountNumber?: string, bankAccountHolderName?: string, hideSoupsOption?: boolean, themePreference?: ThemePreference) => {
        if (bankAccountNumber) {
            try {
                // Validace kódu banky
                if (!bankAccountNumber.includes('/')) {
                    throw new Error("Číslo účtu neobsahuje lomítko/kód banky")
                }
                const split = bankAccountNumber.split("/");
                if (split[1].length !== 4) {
                    throw new Error("Kód banky musí být 4 číslice")
                }
                if (!isValidInteger(split[1])) {
                    throw new Error("Kód banky není číslo")
                }

                // Validace čísla a předčíslí
                let cislo = split[0];

                if (cislo.indexOf('-') > 0) {
                    cislo = cislo.replace('-', '');
                }
                if (!isValidInteger(cislo)) {
                    throw new Error("Předčíslí nebo číslo účtu neobsahuje pouze číslice")
                }
                if (cislo.length < 16) {
                    cislo = cislo.padStart(16, '0');
                }
                let sum = 0;
                for (let i = 0; i < cislo.length; i++) {
                    const char = cislo.charAt(i);
                    const order = (cislo.length - 1) - i;
                    const weight = (2 ** order) % 11;
                    sum += Number.parseInt(char) * weight
                }
                if (sum % 11 !== 0) {
                    throw new Error("Číslo účtu je neplatné")
                }
            } catch (e: any) {
                alert(e.message)
                return
            }
        }
        settings?.setBankAccountNumber(bankAccountNumber);
        settings?.setBankAccountHolderName(bankAccountHolderName);
        settings?.setHideSoupsOption(hideSoupsOption);
        if (themePreference) {
            settings?.setThemePreference(themePreference);
        }
        closeSettingsModal();
    }

    return <Navbar variant='dark' expand="lg">
        <Navbar.Brand href="/">Luncher</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
            <Nav className="nav">
                <button
                    className="theme-toggle"
                    onClick={toggleTheme}
                    title={effectiveDark ? 'Přepnout na světlý režim' : 'Přepnout na tmavý režim'}
                    aria-label="Přepnout světlý/tmavý režim"
                >
                    <FontAwesomeIcon icon={effectiveDark ? faSun : faMoon} />
                </button>
                <HuePicker
                    accentHue={settings?.accentHue ?? 142}
                    isDark={effectiveDark}
                    onChange={hue => settings?.setAccentHue(hue)}
                />
                <NavDropdown align="end" title={auth?.login} id="basic-nav-dropdown">
                    <NavDropdown.Item onClick={() => setSettingsModalOpen(true)}>Nastavení</NavDropdown.Item>
                    <NavDropdown.Item onClick={() => setRefreshMenuModalOpen(true)}>Přenačtení menu</NavDropdown.Item>
                    <NavDropdown.Item onClick={() => navigate(NAVRHY_URL)}>Návrhy na vylepšení</NavDropdown.Item>
                    <NavDropdown.Item onClick={() => setPizzaModalOpen(true)}>Pizza kalkulačka</NavDropdown.Item>
                    <NavDropdown.Item onClick={handleQrMenuClick}>Generování QR kódů</NavDropdown.Item>
                    <NavDropdown.Item onClick={() => navigate(STATS_URL)}>Statistiky</NavDropdown.Item>
                    <NavDropdown.Item onClick={() => navigate(OBJEDNANI_URL)}>Objednání</NavDropdown.Item>
                    <NavDropdown.Item onClick={() => {
                        getChangelogs().then(response => {
                            const entries = response.data ?? {};
                            setChangelogEntries(entries);
                            setChangelogModalOpen(true);
                            const dates = Object.keys(entries).sort((a, b) => b.localeCompare(a));
                            if (dates.length > 0) {
                                localStorage.setItem(LAST_SEEN_CHANGELOG_KEY, dates[0]);
                            }
                        });
                    }}>Novinky</NavDropdown.Item>
                    {IS_DEV && (
                        <>
                            <NavDropdown.Divider />
                            <NavDropdown.Item onClick={() => setGenerateMockModalOpen(true)}>🔧 Generovat mock data</NavDropdown.Item>
                            <NavDropdown.Item onClick={() => setClearMockModalOpen(true)}>🔧 Smazat data dne</NavDropdown.Item>
                        </>
                    )}
                    <NavDropdown.Divider />
                    <NavDropdown.Item onClick={auth?.logout}>Odhlásit se</NavDropdown.Item>
                </NavDropdown>
            </Nav>
        </Navbar.Collapse>
        <SettingsModal isOpen={settingsModalOpen} onClose={closeSettingsModal} onSave={saveSettings} />
        <RefreshMenuModal isOpen={refreshMenuModalOpen} onClose={closeRefreshMenuModal} />
        <PizzaCalculatorModal isOpen={pizzaModalOpen} onClose={closePizzaModal} />
        {choices && settings?.bankAccount && settings?.holderName && (
            <GenerateQrModal
                isOpen={qrModalOpen}
                onClose={closeQrModal}
                choices={choices}
                bankAccount={settings.bankAccount}
                bankAccountHolder={settings.holderName}
            />
        )}
        {IS_DEV && (
            <>
                <GenerateMockDataModal
                    isOpen={generateMockModalOpen}
                    onClose={() => setGenerateMockModalOpen(false)}
                    currentDayIndex={dayIndex}
                />
                <ClearMockDataModal
                    isOpen={clearMockModalOpen}
                    onClose={() => setClearMockModalOpen(false)}
                    currentDayIndex={dayIndex}
                />
            </>
        )}
        <Modal show={changelogModalOpen} onHide={() => setChangelogModalOpen(false)} size="lg">
            <Modal.Header closeButton>
                <Modal.Title><h2>Novinky</h2></Modal.Title>
            </Modal.Header>
            <Modal.Body>
                {Object.keys(changelogEntries).sort((a, b) => b.localeCompare(a)).map(date => (
                    <div key={date}>
                        <strong>{formatDateString(date)}</strong>
                        <ul>
                            {changelogEntries[date].map((item, index) => (
                                <li key={index}>{item}</li>
                            ))}
                        </ul>
                    </div>
                ))}
                {Object.keys(changelogEntries).length === 0 && (
                    <p>Žádné novinky.</p>
                )}
            </Modal.Body>
            <Modal.Footer>
                <Button variant="secondary" onClick={() => setChangelogModalOpen(false)}>
                    Zavřít
                </Button>
            </Modal.Footer>
        </Modal>
    </Navbar>
}
