/**
 * Bots List Page
 * @since 1.1.0
 */

import { useState, useEffect, useCallback, useRef } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import debounce from 'lodash/debounce'
import {
    Bot,
    Plus,
    Edit2,
    Trash2,
    Copy,
    Star,
    MoreVertical,
    Shield,
    ChevronUp,
    ChevronDown,
    Save,
    HelpCircle,
} from 'lucide-react'
import { useBots, useDeleteBot, useDuplicateBot, useSetDefaultBot } from '@/hooks/useBots'
import { useSettings, useUpdateSettings } from '@/hooks/useSettings'
import { useLanguage } from '@/contexts/LanguageContext'
import { PageHeader } from '@/components/layout/PageHeader'
import { Card, CardContent } from '@/components/common/Card'
import { ToggleSwitch } from '@/components/common/ToggleSwitch'
import { botsApi } from '@/api/bots'
import type { Bot as BotType } from '@/types/bot'
import { t, sprintf } from '@/lib/i18n'

const isBotActive = (bot: BotType): boolean =>
    bot.is_active === 1 || bot.is_active === '1' || bot.is_active === true

const isBotTestMode = (bot: BotType): boolean =>
    bot.test_mode === 1 || bot.test_mode === '1' || bot.test_mode === true

export function Bots() {
    const navigate = useNavigate()
    const { data, isLoading } = useBots()
    const deleteBot = useDeleteBot()
    const duplicateBot = useDuplicateBot()
    const setDefaultBot = useSetDefaultBot()

    // Per-language global rules: scoped to the currently selected admin language.
    const { currentLanguage } = useLanguage()
    const { data: settingsData } = useSettings(currentLanguage)
    const updateSettings = useUpdateSettings(currentLanguage)
    const [isGlobalRulesOpen, setIsGlobalRulesOpen] = useState(false)
    const [globalDefaultWelcomeText, setGlobalDefaultWelcomeText] = useState('')
    const [globalRules, setGlobalRules] = useState('')
    const [globalForbiddenTopics, setGlobalForbiddenTopics] = useState('')
    const [globalRulesModified, setGlobalRulesModified] = useState(false)

    // Load global rules from settings (re-runs when language or data changes)
    useEffect(() => {
        if (settingsData?.data) {
            setGlobalDefaultWelcomeText(settingsData.data.global_default_welcome_text || '')
            setGlobalRules(settingsData.data.global_rules || '')
            setGlobalForbiddenTopics(settingsData.data.global_forbidden_topics || '')
            setGlobalRulesModified(false)
        }
    }, [settingsData, currentLanguage])

    const handleSaveGlobalRules = () => {
        updateSettings.mutate(
            { global_default_welcome_text: globalDefaultWelcomeText, global_rules: globalRules, global_forbidden_topics: globalForbiddenTopics },
            {
                onSuccess: () => {
                    setGlobalRulesModified(false)
                },
            }
        )
    }

    if (isLoading) {
        return (
            <div className="flex items-center justify-center min-h-[400px]">
                <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary-600" />
            </div>
        )
    }

    const bots = data?.data?.bots || []

    const handleDelete = async (id: number, name: string) => {
        if (confirm(sprintf(t('Are you sure you want to delete the bot "%s"?'), name))) {
            try {
                await deleteBot.mutateAsync(id)
            } catch {
                alert(t('Failed to delete bot. Please try again.'))
            }
        }
    }

    const handleDuplicate = async (id: number) => {
        try {
            const result = await duplicateBot.mutateAsync(id)
            if (result?.data?.bot?.id) {
                navigate(`/bots/${result.data.bot.id}`)
            }
        } catch {
            alert(t('Failed to duplicate bot. Please try again.'))
        }
    }

    const handleSetDefault = async (id: number) => {
        try {
            await setDefaultBot.mutateAsync(id)
        } catch {
            alert(t('Failed to set default bot. Please try again.'))
        }
    }

    return (
        <div className="space-y-6 animate-fade-in">
            <PageHeader title={t('Bots')} subtitle={sprintf(t('%d bots in system'), bots.length)}>
                <Link to="/bots/new">
                    <button className="flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors">
                        <Plus className="w-4 h-4" />
                        {t('Add Bot')}
                    </button>
                </Link>
            </PageHeader>

            {/* Global Rules & Forbidden Topics Accordion */}
            <Card className="overflow-hidden" data-wizard-id="global-rules">
                <button
                    onClick={() => setIsGlobalRulesOpen(!isGlobalRulesOpen)}
                    className="w-full flex items-center justify-between px-6 py-4 bg-gradient-to-l from-primary-50 to-white hover:from-primary-100 transition-colors"
                >
                    <div className="flex items-center gap-3">
                        <div className="w-10 h-10 rounded-lg bg-primary-100 flex items-center justify-center">
                            <Shield className="w-5 h-5 text-primary-600" />
                        </div>
                        <div className="text-right">
                            <h3 className="font-semibold text-gray-900">{t('Global Rules')}</h3>
                            <p className="text-sm text-gray-500">{t('Rules and forbidden topics that apply to all bots')}</p>
                        </div>
                    </div>
                    <div className="flex items-center gap-3">
                        {globalRulesModified && (
                            <span className="px-2 py-1 text-xs font-medium bg-yellow-100 text-yellow-700 rounded-full">
                                {t('Unsaved changes')}
                            </span>
                        )}
                        {isGlobalRulesOpen ? (
                            <ChevronUp className="w-5 h-5 text-gray-400" />
                        ) : (
                            <ChevronDown className="w-5 h-5 text-gray-400" />
                        )}
                    </div>
                </button>

                {isGlobalRulesOpen && (
                    <div className="border-t border-gray-200">
                        <CardContent className="py-6 space-y-6">
                            {/* Default Opening Text */}
                            <div>
                                <label className="block text-sm font-medium text-gray-700 mb-1">
                                    {t('Default Opening Text')}
                                </label>
                                <p className="text-xs text-gray-500 mb-2">
                                    {t('The opening message displayed by default for bots without a custom opening message')}
                                </p>
                                <input
                                    type="text"
                                    value={globalDefaultWelcomeText}
                                    onChange={(e) => {
                                        setGlobalDefaultWelcomeText(e.target.value)
                                        setGlobalRulesModified(true)
                                    }}
                                    placeholder={t('Hello! How can I help you today?')}
                                    className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent"
                                />
                            </div>

                            <hr className="border-gray-200" />

                            {/* Rules */}
                            <div>
                                <label className="block text-sm font-medium text-gray-700 mb-1">
                                    {t('Rules that must be followed')}
                                </label>
                                <p className="text-xs text-gray-500 mb-2">
                                    {t('These rules apply to all bots in the system without exception')}
                                </p>
                                <textarea
                                    value={globalRules}
                                    onChange={(e) => {
                                        setGlobalRules(e.target.value)
                                        setGlobalRulesModified(true)
                                    }}
                                    placeholder={t('e.g.: Always offer to schedule a meeting, do not make up information not in the knowledge base...')}
                                    rows={3}
                                    className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent resize-none"
                                />
                            </div>

                            {/* Forbidden Topics */}
                            <div>
                                <label className="block text-sm font-medium text-gray-700 mb-1">
                                    {t('Forbidden topics/actions')}
                                </label>
                                <p className="text-xs text-gray-500 mb-2">
                                    {t('Topics that bots will never address under any circumstances')}
                                </p>
                                <textarea
                                    value={globalForbiddenTopics}
                                    onChange={(e) => {
                                        setGlobalForbiddenTopics(e.target.value)
                                        setGlobalRulesModified(true)
                                    }}
                                    placeholder={t('e.g.: Do not discuss competitors, do not give legal advice...')}
                                    rows={3}
                                    className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent resize-none"
                                />
                            </div>

                            {/* Save Button */}
                            <div className="pt-4 border-t border-gray-200 flex justify-end">
                                <button
                                    onClick={handleSaveGlobalRules}
                                    disabled={!globalRulesModified || updateSettings.isPending}
                                    className={`flex items-center gap-2 px-6 py-2.5 rounded-lg transition-all disabled:opacity-50 disabled:cursor-not-allowed ${
                                        globalRulesModified
                                            ? 'bg-amber-500 hover:bg-amber-600 animate-pulse'
                                            : 'bg-primary-600 hover:bg-primary-700'
                                    } text-white`}
                                >
                                    {updateSettings.isPending ? (
                                        <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
                                    ) : (
                                        <Save className="w-4 h-4" />
                                    )}
                                    {updateSettings.isPending ? t('Saving...') : globalRulesModified ? t('Save Changes') : t('Save')}
                                </button>
                            </div>
                        </CardContent>
                    </div>
                )}
            </Card>

            {bots.length === 0 ? (
                <Card>
                    <CardContent className="py-12">
                        <div className="text-center">
                            <Bot className="w-16 h-16 mx-auto mb-4 text-gray-300" />
                            <h3 className="text-lg font-medium text-gray-900 mb-2">{t('No Bots')}</h3>
                            <p className="text-gray-500 mb-4">{t('Create your first bot to get started')}</p>
                            <Link to="/bots/new">
                                <button className="flex items-center gap-2 px-4 py-2 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition-colors mx-auto">
                                    <Plus className="w-4 h-4" />
                                    {t('Add Bot')}
                                </button>
                            </Link>
                        </div>
                    </CardContent>
                </Card>
            ) : (
                <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                    {bots.map((bot) => (
                        <BotCard
                            key={bot.id}
                            bot={bot}
                            onEdit={() => navigate(`/bots/${bot.id}`)}
                            onDelete={() => handleDelete(bot.id, bot.bot_name)}
                            onDuplicate={() => handleDuplicate(bot.id)}
                            onSetDefault={() => handleSetDefault(bot.id)}
                        />
                    ))}
                </div>
            )}
        </div>
    )
}

// Sub-component: Bot Card
interface BotCardProps {
    bot: BotType
    onEdit: () => void
    onDelete: () => void
    onDuplicate: () => void
    onSetDefault: () => void
}

function BotCard({ bot, onEdit, onDelete, onDuplicate, onSetDefault }: BotCardProps) {
    const [showMenu, setShowMenu] = useState(false)
    const [showTestTooltip, setShowTestTooltip] = useState(false)
    const queryClient = useQueryClient()
    const isDefault = bot.is_default === 1 || bot.is_default === '1' || bot.is_default === true

    // ── Local state for instant UI ──
    const [isActive, setIsActive] = useState(() => isBotActive(bot))
    const [isTestMode, setIsTestMode] = useState(() => isBotTestMode(bot))

    // Timestamp of the last user click on ANY toggle in this card.
    // While within the settle window, useEffect sync is suppressed so that
    // stale server refetches can never override the user's local intent.
    const lastToggleRef = useRef(0)
    const SETTLE_MS = 2500 // debounce (500) + server round-trip + refetch buffer

    // Sync from server only when no recent user interaction
    useEffect(() => {
        if (Date.now() - lastToggleRef.current > SETTLE_MS) {
            setIsActive(isBotActive(bot))
        }
    }, [bot.is_active])

    useEffect(() => {
        if (Date.now() - lastToggleRef.current > SETTLE_MS) {
            setIsTestMode(isBotTestMode(bot))
        }
    }, [bot.test_mode])

    // ── Shared helpers ──
    const cancelBotQueries = useCallback(async () => {
        await queryClient.cancelQueries({ queryKey: ['bots'] })
        await queryClient.cancelQueries({ queryKey: ['bot', bot.id] })
    }, [queryClient, bot.id])

    const invalidateBotQueries = useCallback(() => {
        queryClient.invalidateQueries({ queryKey: ['bots'] })
        queryClient.invalidateQueries({ queryKey: ['bot', bot.id] })
    }, [queryClient, bot.id])

    // ── Active toggle: mutation + debounce ──
    const activeMutation = useMutation({
        mutationFn: (newActive: boolean) =>
            botsApi.updateBot(bot.id, newActive
                ? { is_active: true }
                : { is_active: false, test_mode: false }),
        onMutate: () => cancelBotQueries(),
        onError: () => {
            setIsActive(isBotActive(bot))
            setIsTestMode(isBotTestMode(bot))
        },
        onSettled: () => invalidateBotQueries(),
    })

    const debouncedActiveRef = useRef<ReturnType<typeof debounce>>()
    const debouncedActiveSave = useCallback((value: boolean) => {
        if (debouncedActiveRef.current) debouncedActiveRef.current.cancel()
        debouncedActiveRef.current = debounce((v: boolean) => { activeMutation.mutate(v) }, 600)
        debouncedActiveRef.current(value)
    }, [activeMutation])

    const handleActiveToggle = useCallback(() => {
        lastToggleRef.current = Date.now()
        const next = !isActive
        setIsActive(next)
        if (!next) setIsTestMode(false)   // turning off → also disable test mode
        debouncedActiveSave(next)
    }, [isActive, debouncedActiveSave])

    // ── Test-mode toggle: mutation + debounce ──
    const testMutation = useMutation({
        mutationFn: (newTest: boolean) =>
            botsApi.updateBot(bot.id, newTest
                ? { is_active: true, test_mode: true }
                : { test_mode: false }),
        onMutate: () => cancelBotQueries(),
        onError: () => {
            setIsActive(isBotActive(bot))
            setIsTestMode(isBotTestMode(bot))
        },
        onSettled: () => invalidateBotQueries(),
    })

    const debouncedTestRef = useRef<ReturnType<typeof debounce>>()
    const debouncedTestSave = useCallback((value: boolean) => {
        if (debouncedTestRef.current) debouncedTestRef.current.cancel()
        debouncedTestRef.current = debounce((v: boolean) => { testMutation.mutate(v) }, 600)
        debouncedTestRef.current(value)
    }, [testMutation])

    const handleTestModeToggle = useCallback(() => {
        lastToggleRef.current = Date.now()
        const next = !isTestMode
        setIsTestMode(next)
        if (next && !isActive) setIsActive(true)   // turning test on → also enable
        debouncedTestSave(next)
    }, [isTestMode, isActive, debouncedTestSave])

    // Cleanup debounces on unmount
    useEffect(() => () => {
        debouncedActiveRef.current?.cancel()
        debouncedTestRef.current?.cancel()
    }, [])

    const activeLabel = isActive ? t('Active') : t('Inactive')
    const activeLabelColor = isActive ? 'text-green-700' : 'text-gray-500'
    const testLabel = isTestMode ? t('Test mode active') : t('Test mode off')
    const testLabelColor = isTestMode ? 'text-amber-600' : 'text-gray-400'

    return (
        <Card className="relative hover:shadow-lg transition-shadow" data-wizard-id={isDefault ? 'bot-default' : undefined}>
            {/* Default Badge */}
            {isDefault && (
                <div className="absolute top-3 start-3">
                    <span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-amber-100 text-amber-800">
                        <Star className="w-3 h-3 me-1 fill-current" />
                        {t('Default')}
                    </span>
                </div>
            )}

            {/* Actions Menu */}
            <div className="absolute top-3 end-3">
                <div className="relative">
                    <button
                        onClick={() => setShowMenu(!showMenu)}
                        className="p-1 text-gray-400 hover:text-gray-600 rounded"
                    >
                        <MoreVertical className="w-5 h-5" />
                    </button>

                    {showMenu && (
                        <>
                            {/* Overlay to close menu */}
                            <div
                                className="fixed inset-0 z-10"
                                onClick={() => setShowMenu(false)}
                            />
                            <div className="absolute end-0 mt-1 w-48 bg-white rounded-lg shadow-lg border z-20">
                                <button
                                    onClick={() => {
                                        onEdit()
                                        setShowMenu(false)
                                    }}
                                    className="flex items-center gap-2 w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-50 rounded-t-lg"
                                >
                                    <Edit2 className="w-4 h-4" />
                                    {t('Edit')}
                                </button>
                                <button
                                    onClick={() => {
                                        onDuplicate()
                                        setShowMenu(false)
                                    }}
                                    className="flex items-center gap-2 w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-50"
                                >
                                    <Copy className="w-4 h-4" />
                                    {t('Duplicate')}
                                </button>
                                {!isDefault && (
                                    <button
                                        onClick={() => {
                                            onSetDefault()
                                            setShowMenu(false)
                                        }}
                                        className="flex items-center gap-2 w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-50"
                                    >
                                        <Star className="w-4 h-4" />
                                        {t('Set as Default')}
                                    </button>
                                )}
                                <button
                                    onClick={() => {
                                        if (isDefault) {
                                            if (confirm(t('This is the default bot! Are you sure you want to delete it?'))) {
                                                onDelete()
                                            }
                                        } else {
                                            onDelete()
                                        }
                                        setShowMenu(false)
                                    }}
                                    className="flex items-center gap-2 w-full px-4 py-2 text-sm text-red-600 hover:bg-red-50 rounded-b-lg"
                                >
                                    <Trash2 className="w-4 h-4" />
                                    {t('Delete')}
                                </button>
                            </div>
                        </>
                    )}
                </div>
            </div>

            <CardContent className="pt-12 pb-6">
                {/* Bot Icon/Color */}
                <div
                    className="w-16 h-16 rounded-2xl mx-auto mb-4 flex items-center justify-center"
                    style={{ backgroundColor: bot.primary_color || '#3BC2D0' }}
                >
                    <Bot className="w-8 h-8 text-white" />
                </div>

                {/* Name & Description */}
                <h3 className="font-bold text-lg text-center text-gray-900 mb-1">
                    {bot.bot_name}
                </h3>
                <p className="text-sm text-gray-500 text-center mb-4 line-clamp-2">
                    {bot.description || t('No description')}
                </p>

                {/* Active toggle */}
                <div className="flex items-center justify-center gap-2 mb-2">
                    <ToggleSwitch
                        checked={isActive}
                        onChange={handleActiveToggle}
                        ariaLabel={activeLabel}
                    />
                    <span className={`text-xs font-medium ${activeLabelColor}`}>{activeLabel}</span>
                </div>

                {/* Test mode toggle */}
                <div className="flex items-center justify-center gap-2 mb-4">
                    <ToggleSwitch
                        checked={isTestMode}
                        onChange={handleTestModeToggle}
                        ariaLabel={testLabel}
                    />
                    <span className={`text-xs font-medium ${testLabelColor}`}>{testLabel}</span>
                    <div className="relative">
                        <button
                            type="button"
                            className="text-amber-500 hover:text-amber-700 transition-colors"
                            onMouseEnter={() => setShowTestTooltip(true)}
                            onMouseLeave={() => setShowTestTooltip(false)}
                            onClick={() => setShowTestTooltip(!showTestTooltip)}
                            aria-label={t('Test Mode')}
                        >
                            <HelpCircle className="w-3.5 h-3.5" />
                        </button>
                        {showTestTooltip && (
                            <div className="absolute bottom-full mb-2 start-1/2 -translate-x-1/2 z-30 w-56 bg-gray-800 text-white text-xs rounded-lg px-3 py-2 shadow-lg pointer-events-none text-center leading-relaxed">
                                {t('Test mode makes the bot function exactly like an active bot, but it is only visible to logged-in administrators. Use this to preview and test before going live.')}
                            </div>
                        )}
                    </div>
                </div>

                {/* Edit Button */}
                <button
                    onClick={onEdit}
                    className="flex items-center justify-center gap-2 w-full px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors text-sm"
                >
                    <Edit2 className="w-4 h-4" />
                    {t('Edit Settings')}
                </button>
            </CardContent>
        </Card>
    )
}

