import { useEffect } from 'react';
import { Play, Menu, FolderOpen, MessageCircleQuestionMark } from 'lucide-react';
import { AppService } from '@bindings/firefly-launcher/internal/app-service';
import { FSService } from '@bindings/firefly-launcher/internal/fs-service';
import { toast } from 'react-toastify';
import path from 'path-browserify'
import useSettingStore from '@/stores/settingStore';
import useModalStore from '@/stores/modalStore';
import useLauncherStore from '@/stores/launcherStore';
import { motion } from 'motion/react';
import { Link } from '@tanstack/react-router';
import { CheckUpdateLauncher, CheckUpdateProxy, CheckUpdateServer, sleep, UpdateLauncher, UpdateProxy, UpdateServer } from '@/helper';
import UpdateModal from '@/components/updateModal';
import { BackgroundSelector } from '@/components/backgroudModal';


export default function LauncherPage() {
    const { 
        gamePath,
        setGamePath,
        setGameDir,
        serverPath,
        proxyPath,
        gameDir,
        serverVersion,
        proxyVersion,
        background
    } = useSettingStore()

    const {
        isOpenDownloadDataModal,
        isOpenUpdateDataModal,
        isOpenSelfUpdateModal,
        setIsOpenDownloadDataModal,
        setIsOpenUpdateDataModal,
        setIsOpenSelfUpdateModal
    } = useModalStore()

    const {
        isLoading,
        downloadType,
        serverReady,
        proxyReady,
        isDownloading,
        serverRunning,
        proxyRunning,
        gameRunning,
        progressDownload,
        downloadSpeed,
        updateData,
        // launcherVersion,
        setLauncherVersion,
        setIsLoading,
        setDownloadType,
        setServerReady,
        setProxyReady,
        setIsDownloading,
        setServerRunning,
        setProxyRunning,
        setGameRunning,
        setUpdateData,
    } = useLauncherStore()

    const widgetLinks = [
        {
            tooltip: "Firefly SRAnalysis",
            href: "https://sranalysis.kain.id.vn/",
            img: "https://sranalysis.kain.id.vn/ff-sranalysis.png",
            btnClass: "btn-primary"
        },
        {
            tooltip: "Firefly SRTools",
            href: "https://srtools.kain.id.vn/",
            img: "https://srtools.kain.id.vn/ff-srtool.png",
            btnClass: "btn-secondary"
        },
        {
            tooltip: "Amazing's SRTools (Original UI)",
            href: "https://srtools.pages.dev/",
            img: "https://icons.duckduckgo.com/ip3/srtools.pages.dev.ico",
            btnClass: "btn-primary"
        },
        {
            tooltip: "Amazing's SRTools (Modern UI)",
            href: "https://srtools.neonteam.dev/",
            img: "https://icons.duckduckgo.com/ip3/srtools.neonteam.dev.ico",
            btnClass: "btn-secondary"
        }
    ]

    useEffect(() => {
        const check = async () => {
            if (!serverVersion || !proxyVersion) {
                setServerReady(false)
                setProxyReady(false)
                return
            }

            const serverExists = await FSService.FileExists(serverPath)
            const proxyExists = await FSService.FileExists(proxyPath)
            setServerReady(serverExists)
            setProxyReady(proxyExists)
        }

        check()
    }, [serverPath, proxyPath, serverVersion, proxyVersion])

    useEffect(() => {
        const checkStartUp = async (): Promise<void> => {
            const [_, version] = await AppService.GetCurrentLauncherVersion()
            setLauncherVersion(version)
            const launcherData = await CheckUpdateLauncher()
            if (launcherData.isUpdate) {
                setUpdateData({
                    server: { isUpdate: false, isExists: false, version: "" },
                    proxy: { isUpdate: false, isExists: false, version: "" },
                    launcher: launcherData
                })
                setIsOpenSelfUpdateModal(true)
                return
            }
            const serverData = await CheckUpdateServer(serverPath, serverVersion)
            const proxyData = await CheckUpdateProxy(proxyPath, proxyVersion)
            setUpdateData({
                server: serverData,
                proxy: proxyData,
                launcher: launcherData
            })
            const exitGame = await FSService.FileExists(gamePath)
            if (!exitGame) {
                setGameRunning(false)
                setGamePath("")
                setGameDir("")
            }

            if (!serverData.isExists || !proxyData.isExists) {
                setServerReady(false)
                setProxyReady(false)
                setIsOpenDownloadDataModal(true)
                return
            }

            if (serverData.isUpdate || proxyData.isUpdate) {
                setServerReady(true)
                setProxyReady(true)
                setIsOpenUpdateDataModal(true)
                return
            }
            setServerReady(true)
            setProxyReady(true)
        }
        checkStartUp()
    }, []);

    const handlePickFile = async () => {
        try {
            setIsLoading(true)
            const basePath = await FSService.PickFile("exe")
            if (basePath.endsWith("StarRail.exe") || basePath.endsWith("launcher.exe")) {
                const normalized = basePath.replace(/\\/g, '/')
                const folderPath = path.dirname(normalized)
                const fullPath = `${folderPath}/StarRail_Data/StreamingAssets/DesignData/Windows`
                const exists = await FSService.DirExists(fullPath)
                if (!exists) {
                    toast.error('Game directory not found. Please select the correct folder.')
                } else {
                    setGamePath(basePath)
                    setGameDir(folderPath)
                    toast.success('Game path set successfully')
                }
            } else {
                toast.error('Not valid file type')
            }
        } catch (err: any) {
            toast.error('PickFolder error:', err)
        } finally {
            setIsLoading(false)
        }
    }

    const handleStartGame = async () => {
        if (!gamePath) {
            return
        }
        if (gameRunning) {
            return
        }
        try {
            setIsLoading(true)
            if (!proxyRunning && !gamePath.endsWith("launcher.exe")) {
                const [resultProxy, error] = await FSService.StartWithConsole(proxyPath)
                if (!resultProxy) {
                    toast.error('Failed to start proxy: ' + error)
                    return
                }
                setProxyRunning(true)
            }
            await sleep(500)
            if (!serverRunning) {
                const [resultServer, error] = await FSService.StartWithConsole(serverPath)
                if (!resultServer) {
                    toast.error('Failed to start server: ' + error)
                    return
                }
                setServerRunning(true)
            }
            await sleep(1000)
            const gameFolder = await FSService.GetDir(gamePath)
            const fileNeedRemove = await FSService.Join(gameFolder, "StarRail_Data", "Plugins", "x86_64", "AccountPlatNative.dll")
            const fileExists = await FSService.FileExists(fileNeedRemove)
            if (fileExists) {
                await FSService.RemoveFile(fileNeedRemove)
            }
            if (gamePath.endsWith("launcher.exe")) {
                const [resultGame, error] = await FSService.StartWithConsole(gamePath)
                if (!resultGame) {
                    toast.error('Failed to start game: ' + error)
                    return
                }
            } else {
                const [resultGame, error] = await FSService.StartApp(gamePath)
                if (!resultGame) {
                    toast.error('Failed to start game: ' + error)
                    return
                }
            }
            setGameRunning(true)

        } catch (err: any) {
            console.log(err)
            toast.error('StartGame error:', err)
        } finally {
            setIsLoading(false)
        }
    }


    const handlerUpdateData = async () => {
        setIsDownloading(true)
        if (updateData.launcher.isUpdate) {
            await UpdateLauncher(updateData.launcher.version)
            setUpdateData({ ...updateData, launcher: { isUpdate: false, isExists: true, version: updateData.launcher.version } })
            setIsOpenSelfUpdateModal(true)
        }
        if (updateData.server.isUpdate || !updateData.server.isExists) {
            await UpdateServer(updateData.server.version)
            setServerReady(true)
            setUpdateData({ ...updateData, server: { isUpdate: false, isExists: true, version: updateData.server.version } })
        }
        if (updateData.proxy.isUpdate || !updateData.proxy.isExists) {
            await UpdateProxy(updateData.proxy.version)
            setProxyReady(true)
            setUpdateData({ ...updateData, proxy: { isUpdate: false, isExists: true, version: updateData.proxy.version } })
        }

        setDownloadType("")
        setIsDownloading(false)
    }


    // Handle ESC key to close modal
    useEffect(() => {
        const handleEscKey = (event: KeyboardEvent) => {
            if (event.key === 'Escape') {
                setIsOpenDownloadDataModal(false);
                setIsOpenUpdateDataModal(false);
                setIsOpenSelfUpdateModal(false);
            }
        };
        window.addEventListener('keydown', handleEscKey);
        return () => window.removeEventListener('keydown', handleEscKey);
    }, [isOpenDownloadDataModal, isOpenUpdateDataModal, isOpenSelfUpdateModal]);


    return (
        <div className="relative min-h-fit overflow-hidden">
            <img
                src={background}
                alt="background"
                className="fixed inset-0 w-full h-full object-cover z-0"
                onError={(e) => {
                    const target = e.currentTarget as HTMLImageElement
                    target.src = "bg-12.jpg"
                }}
            />

            {/* Header */}
            <header className="hidden sm:flex fixed z-10 items-center justify-between py-6 px-4 ">
                <div className="text-2xl font-bold text-white bg-gray-500/5 rounded-full p-1">Firefly GO</div>
            </header>

            <div className="hidden sm:flex fixed top-1/4 right-4 z-10 flex-col space-y-3 bg-white/5 rounded-xl p-3 shadow-lg">
                {widgetLinks.map((link, idx) => (
                    <div key={idx} className="tooltip tooltip-left" data-tip={link.tooltip}>
                        <a
                            className={`btn btn-circle ${link.btnClass}`}
                            target="_blank"
                            href={link.href}
                        >
                            <img
                                src={link.img}
                                alt={link.tooltip}
                                className="w-8 h-8 rounded-full"
                            />
                        </a>
                    </div>
                ))}

                <div className="tooltip tooltip-left" data-tip="How to use all tools & commands">
                    <Link
                        to="/howto"
                        className="btn btn-warning btn-circle"
                    >
                        <MessageCircleQuestionMark className="w-6 h-6 font-bold rounded-full" />
                    </Link>
                </div>
            </div>

            <div className="hidden sm:flex fixed top-1/2 left-5 z-10 ">
                <BackgroundSelector />
            </div>

            {/* Bottom Panel */}
            {serverReady && proxyReady && !isDownloading && (
                <div className="fixed bottom-0 right-0 p-8 z-10">
                    <div className="flex flex-wrap items-center justify-center gap-2">
                        {gamePath === "" ? (
                            <button
                                className="btn btn-accent btn-xl font-bold"
                                onClick={handlePickFile}
                            >
                                <FolderOpen className="w-6 h-6" />
                                {isLoading ? 'Selecting...' : 'Select Game file'}
                            </button>
                        ) : (
                            <button
                                className="btn btn-warning btn-xl font-bold"
                                onClick={handleStartGame}
                            >
                                <Play className="w-6 h-6" />
                                {isLoading ? 'Selecting...' : gameRunning ? 'Game is running' : 'Start Game'}
                            </button>
                        )}

                        <div className="dropdown dropdown-top dropdown-end">
                            <div tabIndex={0} role="button" className="btn btn-black btn-circle btn-xl m-1">
                                <Menu className="w-6 h-6" />
                            </div>
                            <ul tabIndex={0} className="dropdown-content menu bg-base-100 rounded-box z-1 w-52 p-2 shadow-sm">
                                <li><button onClick={handlePickFile}>Change Game Path</button></li>
                                <li>
                                    <button
                                        onClick={async () => {
                                            const serverData = await CheckUpdateServer(serverPath, serverVersion)
                                            const proxyData = await CheckUpdateProxy(proxyPath, proxyVersion)
                                            setUpdateData({
                                                server: serverData,
                                                proxy: proxyData,
                                                launcher: updateData.launcher
                                            })

                                            if (!serverData.isExists || !proxyData.isExists) {
                                                setIsOpenDownloadDataModal(true)
                                                return
                                            }
                                            if (serverData.isUpdate || proxyData.isUpdate) {
                                                setIsOpenUpdateDataModal(true)
                                                return
                                            }
                                            toast.success("No updates available")
                                        }}>
                                        Check for Updates Server & Proxy
                                    </button>
                                </li>
                                <li>

                                </li>
                                <li><button disabled={!serverPath} onClick={() => {
                                    if (serverPath) {
                                        FSService.OpenFolder("./server")
                                    }
                                }}>Open server folder</button></li>
                                <li><button disabled={!proxyPath} onClick={() => {
                                    if (proxyPath) {
                                        FSService.OpenFolder("./proxy")
                                    }
                                }}>Open proxy folder</button></li>
                                <li><button disabled={!gameDir} onClick={() => {
                                    if (gameDir) {
                                        FSService.OpenFolder(gameDir + "/StarRail_Data/Persistent/Audio/AudioPackage/Windows")
                                    }
                                }}>Open voice folder</button></li>
                            </ul>

                        </div>
                    </div>
                </div>
            )}

            {/* Downloading */}
            {isDownloading && (
                updateData.proxy.isUpdate
                || updateData.server.isUpdate
                || !updateData.proxy.isExists
                || !updateData.server.isExists
            ) && (
                    <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-10 w-[60vw] bg-black/20 backdrop-blur-sm rounded-lg p-4 shadow-lg">
                        <div className="space-y-3">
                            <div className="flex justify-center items-center text-sm text-white/80">
                                <span>{downloadType}</span>
                                <div className="flex items-center gap-4 ml-4">
                                    <span className="text-cyan-400 font-semibold">{downloadSpeed}</span>
                                    <span className="text-white font-bold">{progressDownload.toFixed(1)}%</span>
                                </div>
                            </div>
                            <div className="w-full bg-white/20 rounded-full h-2 overflow-hidden">
                                <motion.div
                                    className="h-full bg-gradient-to-r from-cyan-400 to-blue-500 rounded-full"
                                    initial={{ width: 0 }}
                                    animate={{ width: `${progressDownload}%` }}
                                    transition={{ type: "tween", ease: "linear", duration: 0.03 }}
                                />
                            </div>
                            <div className="text-center text-xs text-white/60">
                                {progressDownload < 100 ? 'Please wait...' : 'Complete!'}
                            </div>
                        </div>
                    </div>
                )}

            {isDownloading && updateData.launcher.isUpdate && (
                <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-10 w-[60vw] bg-black/20 backdrop-blur-sm rounded-lg p-4 shadow-lg">
                    <div className="space-y-3 text-sm text-white/80 text-center">
                        {["update:launcher:downloading", "update:launcher:success", "update:launcher:failed"].includes(downloadType) && (
                            <div className="flex justify-center items-center gap-4 ml-4">
                                <span
                                    className={`font-bold ${downloadType === "update:launcher:downloading"
                                        ? "text-yellow-200 text-2xl"
                                        : downloadType === "update:launcher:success"
                                            ? "text-emerald-200 text-xl"
                                            : "text-red-200 text-xl"
                                        }`}
                                >
                                    {downloadType === "update:launcher:downloading" && "Updating launcher"}
                                    {downloadType === "update:launcher:success" && "Launcher updated successfully, auto closing after 5s"}
                                    {downloadType === "update:launcher:failed" && "Launcher update failed, auto closing after 5s"}
                                    <span className="dot-animation ml-1"></span>
                                </span>
                            </div>
                        )}

                        <div className="text-xs text-white/60">
                            {progressDownload < 100 ? "Please wait..." : "Complete!"}
                        </div>
                    </div>

                    <style>{`
                        .dot-animation::after {
                            content: '';
                            animation: dots 1.2s steps(4, end) infinite;
                        }
                        @keyframes dots {
                            0% { content: ''; }
                            25% { content: '.'; }
                            50% { content: '..'; }
                            75% { content: '...'; }
                            100% { content: ''; }
                        }
                        `}
                    </style>
                </div>
            )}

                <div className="hidden md:block fixed bottom-4 left-5 z-10">

                    <img src="/heart-hsr.gif" alt="firefly animation" className="rounded-lg w-24 h-24" />

                </div>
            {/* Modal */}
            <UpdateModal
                isOpen={isOpenUpdateDataModal}
                onClose={() => setIsOpenUpdateDataModal(false)}
                title="Update Data"
                message="Do you want to update data server and proxy?"
                buttons={[
                    { text: "No", onClick: () => setIsOpenUpdateDataModal(false), variant: "outline" },
                    { text: "Yes", onClick: async () => { setIsOpenUpdateDataModal(false); await handlerUpdateData() }, variant: "primary" }
                ]}
            />

            <UpdateModal
                isOpen={isOpenDownloadDataModal}
                onClose={() => setIsOpenDownloadDataModal(false)}
                title="Download Data"
                message="Data server and proxy download required"
                buttons={[
                    { text: "Download", onClick: async () => { setIsOpenDownloadDataModal(false); await handlerUpdateData() }, variant: "primary" }
                ]}
            />

            <UpdateModal
                isOpen={isOpenSelfUpdateModal}
                onClose={() => setIsOpenSelfUpdateModal(false)}
                title="Update Launcher"
                message="Do you want to update launcher?"
                buttons={[
                    { text: "No", onClick: () => setIsOpenSelfUpdateModal(false), variant: "outline" },
                    { text: "Yes", onClick: async () => { setIsOpenSelfUpdateModal(false); await handlerUpdateData() }, variant: "primary" }
                ]}
            />

        </div>
    )
}
