import React from 'react';
import { AlertCircle, CheckCircle2, LayoutDashboard, Info, Zap, Key, ShieldAlert } from 'lucide-react';
import { clearBacktestRuntimeFlagCache } from '../backtest/flags';
import { fetchDynamicConfigItems, upsertDynamicConfigItems } from '../lib/dynamicConfigApi';
import { useAuth } from '../components/AuthContext';
import { BACKTEST_FLAG_KEYS } from '../../../shared/feature-flags.js';
import { Button, Checkbox, Textarea } from '../components/ui/Primitives';

interface ConfigItem {
    key: string;
    value: string;
    description: string;
}

interface BacktestFlagState {
    enableBacktest: boolean;
    customerEnabled: boolean;
}

const readBooleanConfig = (configs: ConfigItem[], key: string, fallback: boolean = false): boolean => {
    const row = configs.find((item) => item.key === key);
    if (!row) return fallback;
    const normalized = String(row.value || '').trim().toLowerCase();
    if (['true', '1', 'yes', 'on'].includes(normalized)) return true;
    if (['false', '0', 'no', 'off'].includes(normalized)) return false;
    return fallback;
};

export const cloneConfigItems = (configs: ConfigItem[]) =>
    JSON.parse(JSON.stringify(configs)) as ConfigItem[];

export const hasConfigChanges = (configs: ConfigItem[], originalConfigs: ConfigItem[]) =>
    JSON.stringify(configs) !== JSON.stringify(originalConfigs);

export function buildConfigUpsertPayload(configs: ConfigItem[]): ConfigItem[];
export function buildConfigUpsertPayload(configs: ConfigItem[], timestampIso: string): Array<{ key: string; value: string; updated_at: string }>;
export function buildConfigUpsertPayload(configs: ConfigItem[], timestampIso?: string) {
    return configs.map((config) => (
        timestampIso
            ? {
                key: config.key,
                value: config.value,
                updated_at: timestampIso
            }
            : {
                key: config.key,
                value: config.value,
                description: config.description
            }
    ));
}

export const ConfigTab = () => {
    const { profile } = useAuth();
    const isAdmin = profile?.role === 'admin';
    const [configs, setConfigs] = React.useState<ConfigItem[]>([]);
    const [originalConfigs, setOriginalConfigs] = React.useState<ConfigItem[]>([]);
    const [loading, setLoading] = React.useState(true);
    const [saving, setSaving] = React.useState(false);
    const [savingBacktestFlags, setSavingBacktestFlags] = React.useState(false);
    const [backtestFlags, setBacktestFlags] = React.useState<BacktestFlagState>({
        enableBacktest: false,
        customerEnabled: false
    });
    const [message, setMessage] = React.useState<{ type: 'success' | 'error', text: string } | null>(null);

    const fetchConfigs = async () => {
        setLoading(true);
        try {
            const configData = await fetchDynamicConfigItems();
            setConfigs(configData);
            setOriginalConfigs(cloneConfigItems(configData));
            setBacktestFlags({
                enableBacktest: readBooleanConfig(configData, BACKTEST_FLAG_KEYS.ENABLE_BACKTEST, false),
                customerEnabled: readBooleanConfig(configData, BACKTEST_FLAG_KEYS.BACKTEST_CUSTOMER_ENABLED, false)
            });
        } catch (error) {
            console.error('Error fetching global config:', error);
        } finally {
            setLoading(false);
        }
    };

    React.useEffect(() => {
        if (!isAdmin) {
            setLoading(false);
            return;
        }
        fetchConfigs();
    }, [isAdmin]);

    const handleChange = (key: string, value: string) => {
        setConfigs(prev => prev.map(item => item.key === key ? { ...item, value } : item));
    };

    const handleReset = () => {
        setConfigs(cloneConfigItems(originalConfigs));
    };

    const handleSaveAll = async () => {
        setSaving(true);
        try {
            await upsertDynamicConfigItems(buildConfigUpsertPayload(configs));

            clearBacktestRuntimeFlagCache();
            setMessage({ type: 'success', text: 'Runtime configuration updated successfully.' });
            setOriginalConfigs(cloneConfigItems(configs));
            setTimeout(() => setMessage(null), 4000);
        } catch (err: any) {
            setMessage({ type: 'error', text: `Sync failed: ${err.message}` });
        } finally {
            setSaving(false);
        }
    };

    const handleSaveBacktestFlags = async () => {
        setSavingBacktestFlags(true);
        try {
            await upsertDynamicConfigItems([
                {
                    key: BACKTEST_FLAG_KEYS.ENABLE_BACKTEST,
                    value: String(backtestFlags.enableBacktest),
                    description: 'Master switch for /api/backtest/run.'
                },
                {
                    key: BACKTEST_FLAG_KEYS.BACKTEST_CUSTOMER_ENABLED,
                    value: String(backtestFlags.customerEnabled),
                    description: 'Allows non-admin customers to use backtest.'
                }
            ]);
            clearBacktestRuntimeFlagCache();
            await fetchConfigs();
            setMessage({ type: 'success', text: 'Backtest access flags updated.' });
            setTimeout(() => setMessage(null), 4000);
        } catch (err: any) {
            setMessage({ type: 'error', text: `Backtest flag update failed: ${err.message}` });
        } finally {
            setSavingBacktestFlags(false);
        }
    };

    const hasChanges = hasConfigChanges(configs, originalConfigs);

    if (!isAdmin) {
        return (
            <div className="settings-access-panel">
                <p className="settings-panel-eyebrow">Restricted</p>
                <h2>Access denied</h2>
                <p>Global bot configuration is limited to administrator accounts.</p>
            </div>
        );
    }

    if (loading) {
        return (
            <div className="settings-loading-state" role="status">
                <div className="settings-loading-spinner" aria-hidden="true" />
                <p>Loading runtime configuration...</p>
            </div>
        );
    }

    return (
        <div className="settings-config-stack animate-in fade-in duration-700">
            {message && (
                <div className={`settings-feedback settings-feedback--${message.type} animate-in slide-in-from-top-4 duration-500`}>
                    <div className="settings-feedback-icon">
                        {message.type === 'success' ? <CheckCircle2 size={24} /> : <AlertCircle size={24} />}
                    </div>
                    <div>
                        <span>{message.type === 'success' ? 'Saved' : 'Update failed'}</span>
                        <p>{message.text}</p>
                    </div>
                </div>
            )}

            <div className="settings-action-panel">
                <div className="settings-action-heading">
                    <div className="settings-action-icon">
                        <Zap size={30} fill="currentColor" fillOpacity={0.1} />
                    </div>
                    <div>
                        <h2>Bot Runtime Configuration</h2>
                        <p>Core infrastructure settings, providers, and guarded credentials.</p>
                    </div>
                </div>

                <div className="settings-action-controls">
                    {hasChanges && (
                        <Button
                            type="button"
                            onClick={handleReset}
                            variant="ghost"
                            size="sm"
                        >
                            Reset changes
                        </Button>
                    )}
                    <Button
                        type="button"
                        onClick={handleSaveAll}
                        disabled={!hasChanges || saving}
                        size="lg"
                    >
                        {saving ? 'Syncing...' : 'Commit Changes'}
                    </Button>
                </div>
            </div>

            <div className="settings-control-panel">
                <div className="settings-control-header">
                    <div>
                        <h3>Backtest Access Control</h3>
                        <p>
                            Runtime flags in <code>bot_config</code>. Applies automatically on dynamic config refresh.
                        </p>
                    </div>
                    <Button
                        type="button"
                        onClick={handleSaveBacktestFlags}
                        disabled={savingBacktestFlags}
                        variant="outline"
                        size="sm"
                    >
                        {savingBacktestFlags ? 'Saving...' : 'Save Backtest Flags'}
                    </Button>
                </div>
                <div className="settings-toggle-grid">
                    <label className="settings-toggle-card">
                        <Checkbox
                            checked={backtestFlags.enableBacktest}
                            onChange={(event) => setBacktestFlags((prev) => ({
                                ...prev,
                                enableBacktest: event.target.checked,
                                customerEnabled: event.target.checked ? prev.customerEnabled : false
                            }))}
                        />
                        <span>
                            <span>Enable Backtest Globally</span>
                            <small>Master switch for `/api/backtest/run`.</small>
                        </span>
                    </label>
                    <label className="settings-toggle-card">
                        <Checkbox
                            checked={backtestFlags.customerEnabled}
                            disabled={!backtestFlags.enableBacktest}
                            onChange={(event) => setBacktestFlags((prev) => ({ ...prev, customerEnabled: event.target.checked }))}
                        />
                        <span>
                            <span>Enable Backtest For Customers</span>
                            <small>When off, only admin users can run backtests.</small>
                        </span>
                    </label>
                </div>
            </div>

            <div className="table-container overflow-x-auto">
                <table className="pro-table w-full">
                    <thead>
                        <tr>
                            <th className="min-w-[200px]">Parameter Key</th>
                            <th className="min-w-[300px]">Functional Description</th>
                            <th className="min-w-[400px]">Operational Value</th>
                        </tr>
                    </thead>
                    <tbody className="divide-y divide-white/5">
                        {configs.length > 0 ? (
                            configs.map((config) => {
                                const isSecret = config.key.includes('KEY') || config.key.includes('SECRET') || config.key.includes('TOKEN');
                                return (
                                    <tr key={config.key} className="group">
                                        <td className="px-6 py-8 align-top">
                                            <div className="flex items-center gap-4">
                                                <div className={`w-10 h-10 rounded-xl flex items-center justify-center shadow-inner group-hover:scale-110 transition-transform ${isSecret ? 'bg-orange-500/10 text-orange-400 border border-orange-500/20' : 'bg-blue-500/10 text-blue-400 border border-blue-500/20'}`}>
                                                    {isSecret ? <Key size={16} /> : <Zap size={16} />}
                                                </div>
                                                <span className="text-[11px] font-black text-white uppercase tracking-tight break-all">
                                                    {config.key}
                                                </span>
                                            </div>
                                        </td>
                                        <td className="px-6 py-8 align-top">
                                            <p className="text-[11px] text-gray-500 font-bold uppercase tracking-wider leading-relaxed group-hover:text-gray-400 transition-colors">
                                                {config.description || 'Core system constant utilized by the execution engine logic.'}
                                            </p>
                                        </td>
                                        <td className="px-6 py-6">
                                            <div className="relative group/field">
                                                <Textarea
                                                    value={config.value}
                                                    onChange={(e) => handleChange(config.key, e.target.value)}
                                                    className={`w-full bg-black/40 border border-white/5 rounded-2xl px-5 py-4 text-[12px] font-mono font-bold focus:outline-none transition-all min-h-[80px] hover:border-white/10 ${isSecret ? 'text-orange-400 focus:border-orange-500' : 'text-blue-400 focus:border-blue-500'}`}
                                                    rows={2}
                                                />
                                                <div className={`absolute bottom-4 right-4 text-[8px] font-black uppercase tracking-widest opacity-20 group-hover/field:opacity-40 transition-opacity ${isSecret ? 'text-orange-400' : 'text-blue-400'}`}>
                                                    {isSecret ? 'ENCRYPTED' : 'UNSECURED'}
                                                </div>
                                            </div>
                                        </td>
                                    </tr>
                                );
                            })
                        ) : (
                            <tr>
                                <td colSpan={3} className="px-6 py-32 text-center">
                                    <LayoutDashboard size={64} className="mx-auto mb-6 text-gray-800 opacity-40" />
                                    <p className="text-lg font-black text-gray-700 uppercase tracking-[0.3em] opacity-40">Configuration Map Null</p>
                                </td>
                            </tr>
                        )}
                    </tbody>
                </table>
            </div>

            <footer className="settings-info-footer">
                <div className="settings-info-watermark">
                    <ShieldAlert size={160} className="text-blue-400" />
                </div>
                <div className="settings-info-content">
                    <div className="settings-info-icon">
                        <Info size={40} />
                    </div>
                    <div>
                        <h5>Runtime Update Behavior</h5>
                        <p>
                            Updates to <strong>symbols</strong> and <strong>capital</strong> are hot-loaded within the active cycle.
                            Changes to <strong>provider credentials</strong> or <strong>API keys</strong> may require a service restart before every worker uses the new value.
                        </p>
                    </div>
                </div>
            </footer>
        </div>
    );
};
