import { useState, useEffect, useCallback, useRef } from 'react';
import { 
    getAgents, 
    getSessionMessages, 
    fetchWithAuth, 
    updateAgentConfig, 
    getUserConfig, 
    clearSessionHistory, 
    getSessionTokenStatus, 
    getAgentTriggers, 
    createAgentTrigger, 
    deleteAgentTrigger, 
    getUserAccessibleNodes, 
    getSkills, 
    resetAgentMetrics, 
    getAgentCortexFiles, 
    getAgentCortexFile,
    getAllProviders,
    getProviderModels
} from '../../../services/apiService';

export const useAgentDrillDown = (agentId) => {
    const [agent, setAgent] = useState(null);
    const [chatHistory, setChatHistory] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState(null);
    const [overrideText, setOverrideText] = useState("");
    
    // UI State
    const [activeTab, setActiveTab] = useState('config');
    const [editConfig, setEditConfig] = useState(null);
    const [saving, setSaving] = useState(false);
    const [userConfig, setUserConfig] = useState(null);
    const [tokenUsage, setTokenUsage] = useState({ token_count: 0, token_limit: 0, percentage: 0 });
    const [tokenError, setTokenError] = useState(null);
    const [clearing, setClearing] = useState(false);
    const [triggers, setTriggers] = useState([]);
    const [newTriggerType, setNewTriggerType] = useState('cron');
    const [newCronValue, setNewCronValue] = useState('0 * * * *');
    const [newIntervalValue, setNewIntervalValue] = useState(600);
    const [newDefaultPrompt, setNewDefaultPrompt] = useState('');
    const [creatingTrigger, setCreatingTrigger] = useState(false);
    const [modalConfig, setModalConfig] = useState(null);
    const [nodes, setNodes] = useState([]);
    const [allSkills, setAllSkills] = useState([]);
    const [flippedCards, setFlippedCards] = useState({ runtime: false, tokens: false });
    const [allProviders, setAllProviders] = useState([]);
    const [availableModels, setAvailableModels] = useState([]);
    const [fetchingModels, setFetchingModels] = useState(false);

    // Evaluation Hub State
    const [cortexFiles, setCortexFiles] = useState([]);
    const [feedbackContent, setFeedbackContent] = useState("");
    const [rubricContent, setRubricContent] = useState("");
    const [coworkerContent, setCoworkerContent] = useState("");
    const [historyLog, setHistoryLog] = useState([]);
    const [savingGroundTruth, setSavingGroundTruth] = useState(false);
    const [selectedAuditId, setSelectedAuditId] = useState(null);

    // Monitoring & Timer States
    const [runningSeconds, setRunningSeconds] = useState(0);
    const [lastTotalConsumption, setLastTotalConsumption] = useState(null);
    const [previousStatus, setPreviousStatus] = useState('idle');
    const [currentAction, setCurrentAction] = useState(null);
    const [lastAction, setLastAction] = useState(null);
    const [lastActionDuration, setLastActionDuration] = useState(null);
    const [actionStartTime, setActionStartTime] = useState(0);

    const fetchData = useCallback(async () => {
        try {
            const allAgents = await getAgents();
            const found = allAgents.find(a => a.id === agentId);
            if (!found) throw new Error("Agent not found");
            setAgent(found);

            setEditConfig(prev => {
                const base = prev || {
                    name: found.template?.name || "",
                    system_prompt: found.template?.system_prompt_content || found.template?.system_prompt_path || "",
                    max_loop_iterations: found.template?.max_loop_iterations || 20,
                    mesh_node_id: found.mesh_node_id || "",
                    provider_name: found.session?.provider_name || "",
                    model_name: found.session?.model_name || "",
                    restrict_skills: found.session?.restrict_skills || false,
                    allowed_skill_ids: found.session?.skills ? found.session.skills.map(s => s.id) : [],
                    is_locked: found.session?.is_locked || false,
                    auto_clear_history: found.session?.auto_clear_history || false,
                    co_worker_quality_gate: found.template?.co_worker_quality_gate || false,
                    rework_threshold: found.template?.rework_threshold || 80,
                    max_rework_attempts: found.template?.max_rework_attempts || 3
                };

                // Apply fallbacks if userConfig is available
                if (userConfig?.effective) {
                    if (!base.provider_name) {
                        base.provider_name = userConfig.effective.llm?.active_provider || "gemini";
                    }
                    if (!base.model_name) {
                        const defaultProvider = base.provider_name;
                        base.model_name = userConfig.effective.llm?.providers?.[defaultProvider]?.model || "";
                    }
                }
                return base;
            });

            // Fetch Providers
            try {
                const plist = await getAllProviders("llm");
                // Transform list of strings into objects {id, name} for UI compatibility
                const transformed = (plist || []).map(p => ({ id: p, name: p }));
                setAllProviders(transformed);
            } catch(e) {}

            if (found.session_id) {
                const historyResp = await getSessionMessages(found.session_id);
                const formatted = (historyResp.messages || []).map(m => ({
                    text: m.content,
                    isUser: m.sender === 'user',
                    reasoning: m.reasoning_content,
                    status: null,
                    sender: m.sender,
                    timestamp: m.created_at,
                    id: m.id,
                    tool_calls: m.tool_calls,
                    message_metadata: m.message_metadata
                }));
                setChatHistory(formatted);
                
                try {
                    const usage = await getSessionTokenStatus(found.session_id);
                    if (usage.error) {
                        setTokenError(usage.error);
                        setTokenUsage({ token_count: 0, token_limit: 0, percentage: 0 });
                    } else {
                        setTokenUsage(usage);
                        setTokenError(null);
                    }
                } catch(e) {
                    setTokenError(e.message);
                }
            }

            try {
                const tList = await getAgentTriggers(agentId);
                setTriggers(tList);
            } catch(e) {}

            // Cortex files (feedback, rubric, history) are fetched separately
            // only when agent transitions to idle, to avoid blocking gRPC during active runs.
            const isActive = found.status === 'active' || found.status === 'starting';
            const wasActive = prevStatusRef.current === 'active' || prevStatusRef.current === 'starting';
            if (!isActive && (wasActive || prevStatusRef.current === null)) {
                fetchCortexFiles(found);
            }
            prevStatusRef.current = found.status;
        } catch (err) {
            setError(err.message);
        } finally {
            setLoading(false);
        }
    }, [agentId]);

    useEffect(() => {
        const loadConf = async () => {
            try {
                const [conf, nList, sList] = await Promise.all([
                    getUserConfig(),
                    getUserAccessibleNodes(),
                    getSkills()
                ]);
                setUserConfig(conf);
                setNodes(nList);
                setAllSkills(sList);

                // Update editConfig with fallbacks if it was already initialized but empty
                setEditConfig(prev => {
                    if (!prev) return prev;
                    const updated = { ...prev };
                    let changed = false;
                    if (!updated.provider_name) {
                        updated.provider_name = conf.effective?.llm?.active_provider || "gemini";
                        changed = true;
                    }
                    if (!updated.model_name && updated.provider_name) {
                        updated.model_name = conf.effective?.llm?.providers?.[updated.provider_name]?.model || "";
                        changed = true;
                    }
                    return changed ? updated : prev;
                });
            } catch (e) {}
        };
        loadConf();
    }, []);

    // Separate cortex file fetch so blocking gRPC calls don't run every 2.5s
    const fetchCortexFiles = useCallback(async (found) => {
        const sid = found.session?.sync_workspace_id || found.session_id;
        const nodeId = found.mesh_node_id || "hub";
        if (!sid) return;
        try {
            const cFilesListing = await getAgentCortexFiles(agentId, nodeId, sid);
            const files = cFilesListing.files || [];
            setCortexFiles(files);

            const fileExists = (name) => files.some(f => f.name === name || f.path === `.cortex/${name}`);

            if (fileExists("feedback.md")) {
                try {
                    const feedback = await getAgentCortexFile(agentId, nodeId, sid, "feedback.md");
                    setFeedbackContent(feedback?.content || "");
                } catch (e) {}
            }

            if (fileExists("rubric.md")) {
                try {
                    const rubric = await getAgentCortexFile(agentId, nodeId, sid, "rubric.md");
                    setRubricContent(rubric?.content || "");
                } catch (e) {}
            }

            try {
                const coworker = await getAgentCortexFile(agentId, nodeId, sid, ".coworker.md");
                setCoworkerContent(coworker?.content || "");
            } catch (e) {}

            if (fileExists("history.log")) {
                try {
                    const logs = await getAgentCortexFile(agentId, nodeId, sid, "history.log");
                    if (logs?.content) {
                        try {
                            const parsed = JSON.parse(logs.content);
                            setHistoryLog(Array.isArray(parsed) ? parsed : []);
                        } catch (e) {
                            setHistoryLog(logs.content.split('\n').filter(l => l.trim()).map(line => ({ message: line })));
                        }
                    }
                } catch (e) {}
            }
        } catch (e) {}
    }, [agentId]);

    // Track previous status to detect transitions to idle
    const prevStatusRef = useRef(null);

    useEffect(() => {
        fetchData();
        const interval = setInterval(fetchData, 2500);
        return () => clearInterval(interval);
    }, [agentId, fetchData]);

    useEffect(() => {
        let timer = null;
        const isRunning = agent?.status === 'active' || agent?.status === 'starting';
        
        if (isRunning) {
            timer = setInterval(() => {
                setRunningSeconds(s => s + 1);
            }, 1000);
        } else if (previousStatus === 'active' || previousStatus === 'starting') {
            setLastTotalConsumption(runningSeconds);
        }
        
        setPreviousStatus(agent?.status || 'idle');
        return () => { if (timer) clearInterval(timer); };
    }, [agent?.status, previousStatus, runningSeconds]);

    useEffect(() => {
        const isRunning = agent?.status === 'active' || agent?.status === 'starting';
        
        // If it was running and now it's idle, we show a 'Completed' state
        if (!isRunning && (previousStatus === 'active' || previousStatus === 'starting')) {
            setCurrentAction({ 
                display: '✅ Process Complete: Workflow finished successfully', 
                raw: 'completed',
                progress: 100,
                isDone: true 
            });
            return;
        }

        if (!isRunning) return;

        if (previousStatus !== 'active' && previousStatus !== 'starting') {
            setRunningSeconds(0);
            setLastTotalConsumption(null);
            setCurrentAction(null);
            setLastAction(null);
            setLastActionDuration(null);
            setActionStartTime(0);
        }

        const rawStatus = agent?.evaluation_status || 'Orchestrating task payload...';
        
        // Calculate a rough progress percentage based on keywords
        let calculatedProgress = 10;
        const lowStatus = rawStatus.toLowerCase();
        
        if (lowStatus.includes('orchestrating')) calculatedProgress = 15;
        else if (lowStatus.includes('thinking')) calculatedProgress = 30;
        else if (lowStatus.includes('executing')) calculatedProgress = 50;
        else if (lowStatus.includes('audit' || lowStatus.includes('coworker'))) calculatedProgress = 75;
        else if (lowStatus.includes('passed') || lowStatus.includes('finished')) calculatedProgress = 100;
        else if (lowStatus.includes('reworking')) calculatedProgress = 40;

        if (rawStatus !== (currentAction?.raw || '')) {
            const hasPrefix = lowStatus.includes('agent:') || lowStatus.includes('audit:') || lowStatus.includes('co-worker:');
            
            let cleanStatus = rawStatus;
            if (!hasPrefix) {
                cleanStatus = (lowStatus.includes('audit') || lowStatus.includes('worker') || lowStatus.includes('evaluat'))
                    ? `🛡️ Co-Worker Audit: ${rawStatus}` 
                    : `🤖 Main Agent: ${rawStatus}`;
            }

            if (currentAction && !currentAction.isDone) {
                setLastAction(currentAction);
                setLastActionDuration(runningSeconds - actionStartTime);
            }
            
            setCurrentAction({ 
                display: cleanStatus, 
                raw: rawStatus, 
                progress: calculatedProgress,
                isDone: false
            });
            setActionStartTime(runningSeconds);
        } else if (currentAction && currentAction.progress !== calculatedProgress) {
            setCurrentAction(prev => ({ ...prev, progress: calculatedProgress }));
        }
    }, [agent?.status, agent?.evaluation_status, previousStatus, currentAction, runningSeconds, actionStartTime]);

    const handleAction = async (targetStatus) => {
        try {
            await fetchWithAuth(`/agents/${agentId}/status`, {
                method: 'PATCH',
                body: { status: targetStatus }
            });
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Status Change Failed', message: err.message, type: 'error' });
        }
    };

    const handleClearHistory = () => {
        if (!agent?.session_id) return;
        setModalConfig({
            title: 'Confirm Memory Wipe',
            message: "Are you sure you want to clear the agent's memory? This cannot be undone.",
            type: 'error',
            confirmText: 'Clear Memory',
            confirmAction: async () => {
                try {
                    setClearing(true);
                    if (agent?.session?.is_locked && editConfig?.is_locked === false) {
                        await updateAgentConfig(agent.id, { 
                            is_locked: false,
                            mesh_node_id: agent.mesh_node_id || "hub" 
                        });
                    }
                    await clearSessionHistory(agent.session_id);
                    setChatHistory([]);
                    setSelectedAuditId(null);
                    fetchData();
                } catch (err) {
                    setModalConfig({ title: 'Clear Failed', message: err.message, type: 'error' });
                } finally {
                    setClearing(false);
                }
            }
        });
    };

    const handleSaveConfig = async () => {
        try {
            setSaving(true);
            const payload = {
                name: editConfig.name,
                system_prompt: editConfig.system_prompt,
                max_loop_iterations: parseInt(editConfig.max_loop_iterations, 10) || 20,
                mesh_node_id: editConfig.mesh_node_id,
                provider_name: editConfig.provider_name,
                restrict_skills: editConfig.restrict_skills,
                allowed_skill_ids: editConfig.allowed_skill_ids,
                is_locked: editConfig.is_locked,
                auto_clear_history: editConfig.auto_clear_history,
                co_worker_quality_gate: editConfig.co_worker_quality_gate,
                rework_threshold: parseInt(editConfig.rework_threshold, 10),
                max_rework_attempts: parseInt(editConfig.max_rework_attempts, 10)
            };
            
            try {
                await fetchWithAuth(`/agents/${agentId}/status`, { method: "PATCH", body: { status: "idle" } });
            } catch (e) {}
            
            await updateAgentConfig(agentId, payload);
            fetchData();
            setModalConfig({ title: 'Success', message: 'Configuration Saved Successfully!', type: 'success' });
        } catch (err) {
            setModalConfig({ title: 'Save Failed', message: err.message, type: 'error' });
        } finally {
            setSaving(false);
        }
    };

    const handleSaveGroundTruth = async () => {
        try {
            setSavingGroundTruth(true);
            const sid = agent.session?.sync_workspace_id || agent.session_id;
            const nodeId = agent.mesh_node_id || "hub";

            await fetchWithAuth(`/nodes/${nodeId}/fs/touch?X-User-ID=${userConfig?.id || 'agent_ui'}`, {
                method: "POST",
                body: { 
                    path: ".coworker.md",
                    content: coworkerContent,
                    is_dir: false,
                    session_id: sid
                }
            });
            setModalConfig({ title: 'Success', message: 'Auditor Guidelines synced to node workspace.', type: 'success' });
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Update Failed', message: err.message, type: 'error' });
        } finally {
            setSavingGroundTruth(false);
        }
    };

    const handleAddTrigger = async () => {
        try {
            setCreatingTrigger(true);
            const payload = { 
                trigger_type: newTriggerType,
                default_prompt: newDefaultPrompt
            };
            if (newTriggerType === 'cron') payload.cron_expression = newCronValue;
            if (newTriggerType === 'interval') payload.interval_seconds = parseInt(newIntervalValue) || 600;
            
            await createAgentTrigger(agentId, payload);
            setNewDefaultPrompt('');
            setNewCronValue('0 * * * *');
            setNewIntervalValue(600);
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Trigger Failed', message: err.message, type: 'error' });
        } finally {
            setCreatingTrigger(false);
        }
    };

    const handleDeleteTrigger = async (triggerId) => {
        try {
            await deleteAgentTrigger(triggerId);
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Delete Failed', message: err.message, type: 'error' });
        }
    };

    const handleFireTrigger = async (triggerPrompt) => {
        try {
            await fetchWithAuth(`/agents/${agentId}/run`, {
                method: 'POST',
                body: { prompt: triggerPrompt }
            });
            setModalConfig({ title: 'Success', message: 'Agent manual execution started successfully!', type: 'success' });
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Execution Failed', message: err.message, type: 'error' });
        }
    };

    const handleFireWebhook = async (token, triggerPrompt) => {
        try {
            await fetchWithAuth(`/agents/${agentId}/webhook?token=${token}`, {
                method: 'POST',
                body: { prompt: triggerPrompt || "Manual test from UI" }
            });
            setModalConfig({ title: 'Success', message: 'Webhook test trigger sent successfully!', type: 'success' });
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Webhook Failed', message: err.message, type: 'error' });
        }
    };

    const handleResetMetrics = async () => {
        setModalConfig({
            title: 'Confirm Reset Metrics',
            message: "Are you sure you want to reset all execution metrics for this agent? This cannot be undone.",
            type: 'error',
            confirmText: 'Reset Metrics',
            confirmAction: async () => {
                try {
                    setClearing(true);
                    await resetAgentMetrics(agentId);
                    fetchData();
                } catch (err) {
                    setModalConfig({ title: 'Reset Failed', message: err.message, type: 'error' });
                } finally {
                    setClearing(false);
                }
            }
        });
    };

    const handleInjectOverride = async (e) => {
        if (e) e.preventDefault();
        const textToInject = overrideText.trim();
        if (!textToInject) return;
        
        // Optimistically update the UI to prevent "frozen" perception
        setChatHistory(prev => [...prev, {
            id: `temp-${Date.now()}`,
            text: textToInject,
            isUser: true,
            sender: 'user',
            timestamp: new Date().toISOString()
        }]);
        setOverrideText("");

        try {
            await fetchWithAuth(`/agents/${agentId}/run`, {
                method: "POST",
                body: { prompt: textToInject }
            });
            // We no longer show a modal for a successful injection, to mirror a smooth chat experience
            fetchData();
        } catch (err) {
            setModalConfig({ title: 'Injection Failed', message: err.message, type: 'error' });
        }
    };

    useEffect(() => {
        const fetchModels = async () => {
            if (!editConfig?.provider_name) {
                setAvailableModels([]);
                return;
            }
            setFetchingModels(true);
            try {
                const mlist = await getProviderModels(editConfig.provider_name);
                // Extract only the model_name strings for UI compatibility
                const modelNames = (mlist || []).map(m => typeof m === 'object' ? m.model_name : m);
                setAvailableModels(modelNames);
            } catch(e) {
                setAvailableModels([]);
            } finally {
                setFetchingModels(false);
            }
        };
        fetchModels();
    }, [editConfig?.provider_name]);

    return {
        agent, chatHistory, loading, error, activeTab, setActiveTab,
        editConfig, setEditConfig, saving, userConfig, tokenUsage, tokenError,
        clearing, triggers, newTriggerType, setNewTriggerType, newCronValue, setNewCronValue,
        newIntervalValue, setNewIntervalValue, newDefaultPrompt, setNewDefaultPrompt,
        creatingTrigger, modalConfig, setModalConfig, nodes, allSkills, flippedCards, setFlippedCards,
        cortexFiles, feedbackContent, rubricContent, coworkerContent, setCoworkerContent,
        historyLog, savingGroundTruth, selectedAuditId, setSelectedAuditId,
        runningSeconds, lastTotalConsumption, currentAction, lastAction, lastActionDuration,
        handleAction, handleClearHistory, handleSaveConfig, handleSaveGroundTruth, fetchData,
        handleAddTrigger, handleDeleteTrigger, handleFireTrigger, handleFireWebhook,
        handleResetMetrics, handleInjectOverride, overrideText, setOverrideText,
        availableModels, fetchingModels, allProviders
    };
};
