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';

export default function LauncherPage() {
    const { gamePath,
        setGamePath,
        setGameDir,
        serverPath,
        proxyPath,
        gameDir,
        serverVersion,
        proxyVersion,
    } = 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()

    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 = await FSService.StartWithConsole(proxyPath)
                if (!resultProxy) {
                    toast.error('Failed to start proxy')
                    return
                }
                setProxyRunning(true)
            }
            await sleep(500)
            if (!serverRunning) {
                const resultServer = await FSService.StartWithConsole(serverPath)
                if (!resultServer) {
                    toast.error('Failed to start server')
                    return
                }
                setServerRunning(true)
            }
            await sleep(2000)
            if (gamePath.endsWith("launcher.exe")) {
                const resultGame = await FSService.StartWithConsole(gamePath)
                if (!resultGame) {
                    toast.error('Failed to start game')
                    return
                }
            } else {
                const resultGame = await FSService.StartApp(gamePath)
                if (!resultGame) {
                    toast.error('Failed to start game')
                    return
                }
            }
            setGameRunning(true)

        } catch (err: any) {
            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">
            <div
                className="fixed inset-0 z-0 w-full h-full"
                style={{
                    backgroundImage: "url('/bg.jpg')",
                    backgroundSize: "cover",
                    backgroundPosition: "center",
                    backgroundRepeat: "no-repeat"
                }}
            ></div>

            {/* Header */}
            <header className="hidden sm:flex fixed z-10 items-center justify-between p-6">
                <div className="text-2xl font-bold text-white">Firefly GO</div>
            </header>

            <div className="hidden sm:flex fixed top-1/4 left-4 z-10 flex-col space-y-3 bg-black/30 backdrop-blur-md rounded-xl p-3 shadow-lg">

                <div className="tooltip tooltip-right" data-tip="Firefly SRAnalysis">
                    <a
                        className="btn btn-circle btn-primary"
                        target="_blank"
                        href="https://sranalysis.kain.id.vn/"
                    >
                        <img
                            src="https://sranalysis.kain.id.vn/ff-sranalysis.png"
                            alt="SRAnalysis Logo"
                            className="w-8 h-8 rounded-full"
                        />
                    </a>
                </div>

                <div className="tooltip tooltip-right" data-tip="Firefly SRTools">
                    <a
                        className="btn btn-circle btn-secondary"
                        target="_blank"
                        href="https://srtools.kain.id.vn/"
                    >
                        <img
                            src="https://srtools.kain.id.vn/ff-srtool.png"
                            alt="SRTools Logo"
                            className="w-8 h-8 rounded-full"
                        />
                    </a>
                </div>
                <div className="tooltip tooltip-right" data-tip="Amazing's SRTools (Original UI)">
                    <a
                        className="btn btn-circle btn-primary"
                        target="_blank"
                        href="https://srtools.pages.dev/"
                    >
                        <img
                            src="https://icons.duckduckgo.com/ip3/srtools.pages.dev.ico"
                            alt="SRTools Logo"
                            className="w-8 h-8 rounded-full"
                        />
                    </a>
                </div>
                <div className="tooltip tooltip-right" data-tip="Amazing's SRTools (Modern UI)">
                    <a
                        className="btn btn-circle btn-secondary"
                        target="_blank"
                        href="https://srtools.neonteam.dev/"
                    >
                        <img
                            src="https://icons.duckduckgo.com/ip3/srtools.neonteam.dev.ico"
                            alt="SRTools Logo"
                            className="w-8 h-8 rounded-full"
                        />
                    </a>
                </div>

                <div className="tooltip tooltip-right" 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>


            {/* 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)
                                        const launcherData = await CheckUpdateLauncher()
                                        setUpdateData({
                                            server: serverData,
                                            proxy: proxyData,
                                            launcher: launcherData
                                        })
                                        if (launcherData.isUpdate) {
                                            setIsOpenSelfUpdateModal(true)
                                            return
                                        }
                                        if (!serverData.isExists || !proxyData.isExists) {
                                            setIsOpenDownloadDataModal(true)
                                            return
                                        }
                                        if (serverData.isUpdate || proxyData.isUpdate) {
                                            setIsOpenUpdateDataModal(true)
                                            return
                                        }
                                        toast.success("No updates available")
                                    }}>
                                    Check for Updates
                                </button></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>
            )}

            {/* Version Info */}
            {serverReady && proxyReady && !isDownloading && (
                <div className="hidden md:block fixed bottom-4 left-4 z-10 text-sm font-bold bg-black/20 backdrop-blur-sm rounded-lg p-2 shadow">
                    <p className="text-primary">Version server: {serverVersion}</p>
                    <p className="mt-2 text-secondary">Version proxy: {proxyVersion}</p>
                    <p className="mt-2 text-success">Version launcher: {launcherVersion}</p>
                </div>
            )}

            {/* Modal */}
            {isOpenUpdateDataModal && (
                <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
                    <div className="relative w-[90%] max-w-5xl bg-base-100 text-base-content rounded-xl border border-purple-500/50 shadow-lg shadow-purple-500/20">
                        <motion.button
                            whileHover={{ scale: 1.1, rotate: 90 }}
                            transition={{ duration: 0.2 }}
                            className="btn btn-circle btn-md btn-error absolute right-3 top-3"
                            onClick={() => setIsOpenUpdateDataModal(false)}
                        >
                            ✕
                        </motion.button>

                        <div className="border-b border-purple-500/30 px-6 py-4 mb-4">
                            <h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
                                Update Data
                            </h3>
                        </div>

                        <div className="px-6 pb-6">
                            <div className="mb-6">
                                <p className="text-warning text-lg">
                                    Do you want to update data server and proxy?
                                </p>
                            </div>

                            <div className="flex justify-end gap-3">
                                <motion.button
                                    whileHover={{ scale: 1.05 }}
                                    whileTap={{ scale: 0.95 }}
                                    className="btn btn-outline btn-error"
                                    onClick={() => setIsOpenUpdateDataModal(false)}
                                >
                                    No
                                </motion.button>
                                <motion.button
                                    whileHover={{ scale: 1.05 }}
                                    whileTap={{ scale: 0.95 }}
                                    className="btn btn-primary bg-gradient-to-r from-orange-200 to-red-400 border-none"
                                    onClick={async () => {
                                        setIsOpenUpdateDataModal(false)
                                        await handlerUpdateData()
                                    }}
                                >
                                    Yes
                                </motion.button>
                            </div>
                        </div>
                    </div>
                </div>
            )}

            {isOpenDownloadDataModal && (
                <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
                    <div className="relative w-[90%] max-w-5xl bg-base-100 text-base-content rounded-xl border border-purple-500/50 shadow-lg shadow-purple-500/20">
                        <div className="border-b border-purple-500/30 px-6 py-4 mb-4">
                            <h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
                                Download Data
                            </h3>
                        </div>

                        <div className="px-6 pb-6">
                            <div className="mb-6">
                                <p className="text-warning text-lg">
                                    Data server and proxy download required
                                </p>
                            </div>

                            <div className="flex justify-end gap-3">
                                <motion.button
                                    whileHover={{ scale: 1.05 }}
                                    whileTap={{ scale: 0.95 }}
                                    className="btn btn-primary bg-gradient-to-r from-orange-200 to-red-400 border-none"
                                    onClick={async () => {
                                        setIsOpenDownloadDataModal(false)
                                        await handlerUpdateData()
                                    }}
                                >
                                    Download
                                </motion.button>
                            </div>
                        </div>
                    </div>
                </div>
            )}

            {isOpenSelfUpdateModal && (
                <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 backdrop-blur-sm">
                    <div className="relative w-[90%] max-w-5xl bg-base-100 text-base-content rounded-xl border border-purple-500/50 shadow-lg shadow-purple-500/20">
                        <motion.button
                            whileHover={{ scale: 1.1, rotate: 90 }}
                            transition={{ duration: 0.2 }}
                            className="btn btn-circle btn-md btn-error absolute right-3 top-3"
                            onClick={() => setIsOpenSelfUpdateModal(false)}
                        >
                            ✕
                        </motion.button>

                        <div className="border-b border-purple-500/30 px-6 py-4 mb-4">
                            <h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
                                Update Launcher
                            </h3>
                        </div>

                        <div className="px-6 pb-6">
                            <div className="mb-6">
                                <p className="text-warning text-lg">
                                    Do you want to update launcher?
                                </p>
                            </div>

                            <div className="flex justify-end gap-3">
                                <motion.button
                                    whileHover={{ scale: 1.05 }}
                                    whileTap={{ scale: 0.95 }}
                                    className="btn btn-outline btn-error"
                                    onClick={() => setIsOpenSelfUpdateModal(false)}
                                >
                                    No
                                </motion.button>
                                <motion.button
                                    whileHover={{ scale: 1.05 }}
                                    whileTap={{ scale: 0.95 }}
                                    className="btn btn-primary bg-gradient-to-r from-orange-200 to-red-400 border-none"
                                    onClick={async () => {
                                        setIsOpenSelfUpdateModal(false)
                                        await handlerUpdateData()
                                    }}
                                >
                                    Yes
                                </motion.button>
                            </div>
                        </div>
                    </div>
                </div>
            )}
        </div>
    )
}
