import { useState, useEffect } from "react";
import { toast } from "sonner";
import { Loader2, Save, RefreshCw, Smartphone, Coins, Trophy, Shield, Users, Terminal, MessageSquare } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent } from "@/components/ui/card";

// Types matching the backend response
interface RoleOption { id: string; name: string; color: string; }
interface ChannelOption { id: string; name: string; type: number; }

interface SettingsMeta {
    roles: RoleOption[];
    channels: ChannelOption[];
    commands: { name: string; category: string }[];
}

import { type GameConfigType } from "@shared/lib/config";

// Recursive partial type for nested updates
type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

export function Settings() {
    // We use a DeepPartial type for the local form state to allow for safe updates
    const [config, setConfig] = useState<DeepPartial<GameConfigType> | null>(null);
    const [meta, setMeta] = useState<SettingsMeta>({ roles: [], channels: [], commands: [] });
    const [loading, setLoading] = useState(true);
    const [saving, setSaving] = useState(false);
    const [activeTab, setActiveTab] = useState("general");

    useEffect(() => {
        fetchData();
    }, []);

    const fetchData = async () => {
        setLoading(true);
        try {
            const [configRes, metaRes] = await Promise.all([
                fetch("/api/settings"),
                fetch("/api/settings/meta")
            ]);

            if (configRes.ok && metaRes.ok) {
                const configData = await configRes.json();
                const metaData = await metaRes.json();
                setConfig(configData);
                setMeta(metaData);
            }
        } catch (error) {
            console.error("Failed to fetch settings:", error);
        } finally {
            setLoading(false);
        }
    };

    const handleSave = async () => {
        setSaving(true);
        const toastId = toast.loading("Saving configuration...");
        try {
            const response = await fetch("/api/settings", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify(config)
            });

            if (!response.ok) throw new Error("Failed to save");
            // Reload to satisfy any server-side transformations
            await fetchData();
            toast.success("Settings saved successfully", { id: toastId });
        } catch (error) {
            console.error("Failed to save settings:", error);
            toast.error("Failed to save settings", {
                id: toastId,
                description: "Please check your input and try again."
            });
        } finally {
            setSaving(false);
        }
    };

    // Helper to update nested state
    const updateConfig = (path: string, value: any) => {
        if (!path) return;
        setConfig((prev: any) => {
            const newConfig = { ...prev };
            const parts = path.split('.');
            let current = newConfig;

            for (let i = 0; i < parts.length - 1; i++) {
                const part = parts[i];
                if (part === undefined) return prev;
                // Clone nested objects to ensure immutability
                if (!current[part]) current[part] = {};
                current[part] = { ...current[part] };
                current = current[part];
            }

            const lastPart = parts[parts.length - 1];
            if (lastPart !== undefined) {
                current[lastPart] = value;
            }

            return newConfig;
        });
    };

    if (loading || !config) {
        return (
            <div className="flex items-center justify-center h-[50vh]">
                <Loader2 className="h-8 w-8 animate-spin text-primary" />
            </div>
        );
    }

    const tabs = [
        { id: "general", label: "General", icon: Smartphone },
        { id: "economy", label: "Economy", icon: Coins },
        { id: "leveling", label: "Leveling", icon: Trophy },
        { id: "moderation", label: "Moderation", icon: Shield },
        { id: "roles", label: "Roles", icon: Users },
        { id: "system", label: "System", icon: Terminal },
    ];

    return (
        <div className="space-y-6">
            <div className="flex items-center justify-between">
                <div>
                    <h2 className="text-3xl font-bold tracking-tight text-white drop-shadow-md">Settings</h2>
                    <p className="text-white/60">Manage global bot configuration</p>
                </div>
                <div className="flex items-center gap-2">
                    <Button variant="outline" size="sm" onClick={fetchData} className="glass border-white/10 hover:bg-white/10">
                        <RefreshCw className="h-4 w-4 mr-2" />
                        Reset
                    </Button>
                    <Button onClick={handleSave} disabled={saving} className="bg-primary hover:bg-primary/80 text-primary-foreground shadow-[0_0_15px_rgba(var(--primary),0.3)]">
                        {saving ? <Loader2 className="h-4 w-4 mr-2 animate-spin" /> : <Save className="h-4 w-4 mr-2" />}
                        Save Changes
                    </Button>
                </div>
            </div>

            {/* Tabs Navigation */}
            <div className="flex items-center gap-2 overflow-x-auto pb-2">
                {tabs.map((tab) => (
                    <button
                        key={tab.id}
                        onClick={() => setActiveTab(tab.id)}
                        className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-all border ${activeTab === tab.id
                            ? "bg-primary/20 border-primary/50 text-white shadow-[0_0_10px_rgba(var(--primary),0.2)]"
                            : "bg-white/5 border-white/5 text-white/50 hover:bg-white/10 hover:text-white"
                            }`}
                    >
                        <tab.icon className="h-4 w-4" />
                        <span className="font-medium">{tab.label}</span>
                    </button>
                ))}
            </div>

            <Card className="glass border-white/10">
                <CardContent className="p-6">
                    {activeTab === "general" && (
                        <div className="space-y-6">
                            <SectionTitle icon={MessageSquare} title="Channels" description="Default channels for bot interactions" />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <SelectField
                                    label="Welcome Channel"
                                    value={config?.welcomeChannelId}
                                    options={meta.channels}
                                    onChange={(v) => updateConfig("welcomeChannelId", v)}
                                />
                                <SelectField
                                    label="Feedback Channel"
                                    value={config?.feedbackChannelId}
                                    options={meta.channels}
                                    onChange={(v) => updateConfig("feedbackChannelId", v)}
                                />
                            </div>

                            <SectionTitle icon={Terminal} title="Terminal" description="Dedicated channel for CLI-like interactions" />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <SelectField
                                    label="Terminal Channel"
                                    value={config?.terminal?.channelId}
                                    options={meta.channels}
                                    onChange={(v) => updateConfig("terminal.channelId", v)}
                                />
                                <InputField
                                    label="Terminal Message ID"
                                    value={config?.terminal?.messageId}
                                    onChange={(v) => updateConfig("terminal.messageId", v)}
                                    placeholder="ID of the pinned message"
                                />
                            </div>
                        </div>
                    )}

                    {activeTab === "economy" && (
                        <div className="space-y-6">
                            <SectionTitle icon={Coins} title="Daily Rewards" description="Configure daily currency claims" />
                            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                                <InputField
                                    label="Base Amount"
                                    type="number"
                                    value={config?.economy?.daily?.amount}
                                    onChange={(v) => updateConfig("economy.daily.amount", v)}
                                />
                                <InputField
                                    label="Streak Bonus"
                                    type="number"
                                    value={config?.economy?.daily?.streakBonus}
                                    onChange={(v) => updateConfig("economy.daily.streakBonus", v)}
                                />
                                <InputField
                                    label="Weekly Bonus"
                                    type="number"
                                    value={config?.economy?.daily?.weeklyBonus}
                                    onChange={(v) => updateConfig("economy.daily.weeklyBonus", v)}
                                />
                            </div>

                            <SectionTitle icon={RefreshCw} title="Transfers" description="Rules for player-to-player transfers" />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <InputField
                                    label="Minimum Amount"
                                    type="number"
                                    value={config?.economy?.transfers?.minAmount}
                                    onChange={(v) => updateConfig("economy.transfers.minAmount", v)}
                                />
                                <div className="flex items-center justify-between p-4 rounded-lg bg-white/5 border border-white/5">
                                    <span className="text-sm font-medium">Allow Self Transfer</span>
                                    <input
                                        type="checkbox"
                                        checked={config?.economy?.transfers?.allowSelfTransfer ?? false}
                                        onChange={(e) => updateConfig("economy.transfers.allowSelfTransfer", e.target.checked)}
                                        className="h-5 w-5 rounded border-white/10 bg-white/5"
                                    />
                                </div>
                            </div>

                            <SectionTitle icon={Trophy} title="Lootdrops" description="Random event configuration" />
                            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                                <InputField
                                    label="Spawn Chance"
                                    type="number"
                                    value={config?.lootdrop?.spawnChance}
                                    onChange={(v) => updateConfig("lootdrop.spawnChance", Number(v))}
                                />
                                <InputField
                                    label="Cooldown (ms)"
                                    type="number"
                                    value={config?.lootdrop?.cooldownMs}
                                    onChange={(v) => updateConfig("lootdrop.cooldownMs", Number(v))}
                                />
                                <InputField
                                    label="Min Messages"
                                    type="number"
                                    value={config?.lootdrop?.minMessages}
                                    onChange={(v) => updateConfig("lootdrop.minMessages", Number(v))}
                                />
                                <InputField
                                    label="Reward Min"
                                    type="number"
                                    value={config?.lootdrop?.reward?.min}
                                    onChange={(v) => updateConfig("lootdrop.reward.min", Number(v))}
                                />
                                <InputField
                                    label="Reward Max"
                                    type="number"
                                    value={config?.lootdrop?.reward?.max}
                                    onChange={(v) => updateConfig("lootdrop.reward.max", Number(v))}
                                />
                            </div>
                        </div>
                    )}

                    {activeTab === "leveling" && (
                        <div className="space-y-6">
                            <SectionTitle icon={Trophy} title="XP Formula" description="Calculate level requirements" />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <InputField
                                    label="Base XP"
                                    type="number"
                                    value={config?.leveling?.base}
                                    onChange={(v) => updateConfig("leveling.base", Number(v))}
                                />
                                <InputField
                                    label="Exponent"
                                    type="number"
                                    value={config?.leveling?.exponent}
                                    onChange={(v) => updateConfig("leveling.exponent", Number(v))}
                                />
                            </div>

                            <SectionTitle icon={MessageSquare} title="Chat XP" description="XP gained from text messages" />
                            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                                <InputField
                                    label="Min XP"
                                    type="number"
                                    value={config?.leveling?.chat?.minXp}
                                    onChange={(v) => updateConfig("leveling.chat.minXp", Number(v))}
                                />
                                <InputField
                                    label="Max XP"
                                    type="number"
                                    value={config?.leveling?.chat?.maxXp}
                                    onChange={(v) => updateConfig("leveling.chat.maxXp", Number(v))}
                                />
                                <InputField
                                    label="Cooldown (ms)"
                                    type="number"
                                    value={config?.leveling?.chat?.cooldownMs}
                                    onChange={(v) => updateConfig("leveling.chat.cooldownMs", Number(v))}
                                />
                            </div>
                        </div>
                    )}

                    {activeTab === "roles" && (
                        <div className="space-y-6">
                            <SectionTitle icon={Users} title="System Roles" description="Map discord roles to bot functions" />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <SelectField
                                    label="Student Role"
                                    value={config?.studentRole}
                                    options={meta.roles}
                                    onChange={(v) => updateConfig("studentRole", v)}
                                />
                                <SelectField
                                    label="Visitor Role"
                                    value={config?.visitorRole}
                                    options={meta.roles}
                                    onChange={(v) => updateConfig("visitorRole", v)}
                                />
                            </div>

                            <SectionTitle icon={Terminal} title="Color Roles" description="Roles that players can buy/equip for username colors" />
                            {/* Multi-select for color roles is complex, simpler impl for now */}
                            <div className="p-4 rounded-lg bg-white/5 border border-white/5 space-y-2">
                                <p className="text-sm text-white/60 mb-2">Available Color Roles</p>
                                <div className="flex flex-wrap gap-2">
                                    {(config?.colorRoles || []).map((roleId: string | undefined) => {
                                        if (!roleId) return null;
                                        const role = meta.roles.find(r => r.id === roleId);
                                        return (
                                            <span key={roleId} className="px-2 py-1 rounded bg-white/10 text-xs flex items-center gap-1">
                                                <span className="w-2 h-2 rounded-full" style={{ backgroundColor: role?.color || '#999' }} />
                                                {role?.name || roleId}
                                                <button
                                                    onClick={() => updateConfig("colorRoles", (config?.colorRoles || []).filter((id: string | undefined) => id !== roleId))}
                                                    className="hover:text-red-400 ml-1"
                                                >
                                                    ×
                                                </button>
                                            </span>
                                        );
                                    })}
                                </div>
                                <div className="mt-2">
                                    <select
                                        className="w-full bg-black/20 border border-white/10 rounded-md p-2 text-sm text-white mt-2"
                                        onChange={(e) => {
                                            if (e.target.value && !(config?.colorRoles || []).includes(e.target.value)) {
                                                updateConfig("colorRoles", [...(config?.colorRoles || []), e.target.value]);
                                            }
                                            e.target.value = "";
                                        }}
                                    >
                                        <option value="">+ Add Color Role</option>
                                        {meta.roles.map(r => (
                                            <option key={r.id} value={r.id} style={{ color: r.color }}>{r.name}</option>
                                        ))}
                                    </select>
                                </div>
                            </div>
                        </div>
                    )}
                    {activeTab === "moderation" && (
                        <div className="space-y-6">
                            <SectionTitle icon={Shield} title="Pruning" description="Batch message deletion config" />
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <InputField
                                    label="Max Prune Amount"
                                    type="number"
                                    value={config?.moderation?.prune?.maxAmount}
                                    onChange={(v) => updateConfig("moderation.prune.maxAmount", Number(v))}
                                />
                                <InputField
                                    label="Confirmation Threshold"
                                    type="number"
                                    value={config?.moderation?.prune?.confirmThreshold}
                                    onChange={(v) => updateConfig("moderation.prune.confirmThreshold", Number(v))}
                                />
                            </div>
                        </div>
                    )}

                    {activeTab === "system" && (
                        <div className="space-y-6">
                            <SectionTitle icon={Terminal} title="Commands" description="Enable or disable specific bot commands" />

                            {meta.commands.length === 0 ? (
                                <div className="text-center py-8 text-white/30">
                                    No commands found in metadata.
                                </div>
                            ) : (
                                Object.entries(
                                    meta.commands.reduce((acc, cmd) => {
                                        const cat = cmd.category || 'Uncategorized';
                                        if (!acc[cat]) acc[cat] = [];
                                        acc[cat].push(cmd);
                                        return acc;
                                    }, {} as Record<string, typeof meta.commands>)
                                ).sort(([a], [b]) => a.localeCompare(b)).map(([category, commands]) => (
                                    <div key={category} className="mb-6 last:mb-0">
                                        <h4 className="text-sm font-semibold text-white/40 uppercase tracking-wider mb-3 px-1">{category}</h4>
                                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                                            {commands.map(cmd => (
                                                <div key={cmd.name} className="flex items-center justify-between p-3 rounded-lg bg-white/5 border border-white/5 hover:border-white/10 transition-colors">
                                                    <div className="flex flex-col">
                                                        <span className="text-sm font-medium text-white">/{cmd.name}</span>
                                                        <span className={`text-[10px] ${config?.commands?.[cmd.name] === false ? "text-red-400" : "text-green-400"}`}>
                                                            {config?.commands?.[cmd.name] === false ? "Disabled" : "Enabled"}
                                                        </span>
                                                    </div>
                                                    <input
                                                        type="checkbox"
                                                        checked={config?.commands?.[cmd.name] !== false}
                                                        onChange={(e) => updateConfig(`commands.${cmd.name}`, e.target.checked)}
                                                        className="h-4 w-4 rounded border-white/10 bg-white/5 accent-primary cursor-pointer"
                                                    />
                                                </div>
                                            ))}
                                        </div>
                                    </div>
                                ))
                            )}
                        </div>
                    )}
                </CardContent>
            </Card>
        </div>
    );
}

// Sub-components for cleaner code

function SectionTitle({ icon: Icon, title, description }: { icon: any, title: string, description: string }) {
    return (
        <div className="flex items-start gap-3 border-b border-white/5 pb-2 mb-4">
            <div className="p-2 rounded-lg bg-primary/10 text-primary">
                <Icon className="h-5 w-5" />
            </div>
            <div>
                <h3 className="text-lg font-bold text-white leading-none">{title}</h3>
                <p className="text-sm text-white/40 mt-1">{description}</p>
            </div>
        </div>
    );
}

function InputField({ label, value, onChange, type = "text", placeholder }: { label: string, value: any, onChange: (val: string) => void, type?: string, placeholder?: string }) {
    return (
        <div className="space-y-1.5">
            <label className="text-xs font-medium text-white/60 ml-1">{label}</label>
            <Input
                type={type}
                value={value ?? ""}
                onChange={(e) => onChange(e.target.value)}
                placeholder={placeholder}
                className="bg-black/20 border-white/10 text-white focus:border-primary/50"
            />
        </div>
    );
}

function SelectField({ label, value, options, onChange }: { label: string, value: string | undefined, options: any[], onChange: (val: string) => void }) {
    return (
        <div className="space-y-1.5">
            <label className="text-xs font-medium text-white/60 ml-1">{label}</label>
            <div className="relative">
                <select
                    value={value || ""}
                    onChange={(e) => onChange(e.target.value)}
                    className="flex h-10 w-full rounded-md border border-white/10 bg-black/20 px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-white appearance-none"
                >
                    <option value="" className="bg-zinc-900 text-white/50">Select...</option>
                    {options.map((opt) => (
                        <option key={opt.id} value={opt.id} className="bg-zinc-900">
                            {opt.name}
                        </option>
                    ))}
                </select>
                <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-white/50">
                    <svg className="h-4 w-4 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /></svg>
                </div>
            </div>
        </div>
    );
}
