/**
 * Agent Audit State Hook
 * Centralized state management using useReducer
 */

import { useReducer, useCallback, useMemo, useRef } from "react";
import type {
  AgentAuditState,
  AgentAuditAction,
  LogItem,
  AgentTask,
  AgentFinding,
  AgentTreeResponse,
  ConnectionStatus,
} from "../types";
import { createLogItem, filterLogsByAgent, buildAgentTree } from "../utils";
import type { AgentTreeNode } from "@/shared/api/agentTasks";

// ============ Initial State ============

const initialState: AgentAuditState = {
  task: null,
  findings: [],
  agentTree: null,
  logs: [],
  selectedAgentId: null,
  showAllLogs: true,
  isLoading: false,
  error: null,
  connectionStatus: 'disconnected',
  isAutoScroll: true,
  expandedLogIds: new Set(),
};

// ============ Reducer ============

function agentAuditReducer(state: AgentAuditState, action: AgentAuditAction): AgentAuditState {
  switch (action.type) {
    case 'SET_TASK':
      return { ...state, task: action.payload };

    case 'SET_FINDINGS':
      return { ...state, findings: action.payload };

    case 'ADD_FINDING': {
      // 🔥 添加单个 finding，避免重复
      const newFinding = action.payload;
      const existingIds = new Set(state.findings.map(f => f.id));
      if (newFinding.id && existingIds.has(newFinding.id)) {
        return state; // 已存在，不添加
      }
      return { ...state, findings: [...state.findings, newFinding as AgentFinding] };
    }

    case 'SET_AGENT_TREE':
      return { ...state, agentTree: action.payload };

    case 'SET_LOGS':
      return { ...state, logs: action.payload };

    case 'ADD_LOG': {
      const newLog = createLogItem(action.payload);
      return { ...state, logs: [...state.logs, newLog] };
    }

    case 'UPDATE_LOG': {
      const { id, updates } = action.payload;
      return {
        ...state,
        logs: state.logs.map(log =>
          log.id === id ? { ...log, ...updates } : log
        ),
      };
    }

    case 'REMOVE_LOG':
      return {
        ...state,
        logs: state.logs.filter(log => log.id !== action.payload),
      };

    case 'COMPLETE_TOOL_LOG': {
      const { toolName, output, duration } = action.payload;
      const updatedLogs = [...state.logs];
      for (let i = updatedLogs.length - 1; i >= 0; i--) {
        const log = updatedLogs[i];
        if (log.type === 'tool' && log.tool?.name === toolName && log.tool?.status === 'running') {
          const previousContent = log.content || '';
          updatedLogs[i] = {
            ...log,
            title: `Completed: ${toolName}`,
            content: `${previousContent}\n\nOutput:\n${output}`,
            tool: { name: toolName, duration, status: 'completed' },
          };
          break;
        }
      }
      return { ...state, logs: updatedLogs };
    }

    case 'UPDATE_OR_ADD_PROGRESS_LOG': {
      const { progressKey, title, agentName, time } = action.payload;
      // 查找是否已存在相同 progressKey 的进度日志
      const existingIndex = state.logs.findIndex(
        log => log.type === 'progress' && log.progressKey === progressKey
      );

      if (existingIndex >= 0) {
        // 更新现有日志的 title 和 time
        const updatedLogs = [...state.logs];
        updatedLogs[existingIndex] = {
          ...updatedLogs[existingIndex],
          title,
          time: time || new Date().toLocaleTimeString('en-US', { hour12: false }),
        };
        return { ...state, logs: updatedLogs };
      } else {
        // 添加新的进度日志
        const newLog = createLogItem({
          type: 'progress',
          title,
          progressKey,
          agentName,
          time,
        });
        return { ...state, logs: [...state.logs, newLog] };
      }
    }

    case 'SELECT_AGENT':
      return {
        ...state,
        selectedAgentId: action.payload,
        showAllLogs: action.payload === null,
      };

    case 'TOGGLE_SHOW_ALL_LOGS':
      return {
        ...state,
        showAllLogs: !state.showAllLogs,
        selectedAgentId: state.showAllLogs ? state.selectedAgentId : null,
      };

    case 'SET_LOADING':
      return { ...state, isLoading: action.payload };

    case 'SET_ERROR':
      return { ...state, error: action.payload };

    case 'SET_CONNECTION_STATUS':
      return { ...state, connectionStatus: action.payload };

    case 'SET_AUTO_SCROLL':
      return { ...state, isAutoScroll: action.payload };

    case 'TOGGLE_LOG_EXPANDED': {
      const newExpanded = new Set(state.expandedLogIds);
      if (newExpanded.has(action.payload)) {
        newExpanded.delete(action.payload);
      } else {
        newExpanded.add(action.payload);
      }
      return { ...state, expandedLogIds: newExpanded };
    }

    case 'RESET':
      return { ...initialState };

    default:
      return state;
  }
}

// ============ Hook ============

export function useAgentAuditState() {
  const [state, dispatch] = useReducer(agentAuditReducer, initialState);
  const currentThinkingId = useRef<string | null>(null);
  const currentAgentName = useRef<string | null>(null);

  // ============ Action Creators ============

  const setTask = useCallback((task: AgentTask) => {
    dispatch({ type: 'SET_TASK', payload: task });
  }, []);

  const setFindings = useCallback((findings: AgentFinding[]) => {
    dispatch({ type: 'SET_FINDINGS', payload: findings });
  }, []);

  const setAgentTree = useCallback((tree: AgentTreeResponse) => {
    dispatch({ type: 'SET_AGENT_TREE', payload: tree });
  }, []);

  const addLog = useCallback((log: Omit<LogItem, 'id' | 'time'> & { id?: string; time?: string }): string => {
    const newLog = createLogItem(log);
    dispatch({ type: 'ADD_LOG', payload: newLog });
    return newLog.id;
  }, []);

  const updateLog = useCallback((id: string, updates: Partial<LogItem>) => {
    dispatch({ type: 'UPDATE_LOG', payload: { id, updates } });
  }, []);

  const removeLog = useCallback((id: string) => {
    dispatch({ type: 'REMOVE_LOG', payload: id });
  }, []);

  const selectAgent = useCallback((id: string | null) => {
    dispatch({ type: 'SELECT_AGENT', payload: id });
  }, []);

  const toggleShowAllLogs = useCallback(() => {
    dispatch({ type: 'TOGGLE_SHOW_ALL_LOGS' });
  }, []);

  const setLoading = useCallback((loading: boolean) => {
    dispatch({ type: 'SET_LOADING', payload: loading });
  }, []);

  const setError = useCallback((error: string | null) => {
    dispatch({ type: 'SET_ERROR', payload: error });
  }, []);

  const setConnectionStatus = useCallback((status: ConnectionStatus) => {
    dispatch({ type: 'SET_CONNECTION_STATUS', payload: status });
  }, []);

  const setAutoScroll = useCallback((enabled: boolean) => {
    dispatch({ type: 'SET_AUTO_SCROLL', payload: enabled });
  }, []);

  const toggleLogExpanded = useCallback((id: string) => {
    dispatch({ type: 'TOGGLE_LOG_EXPANDED', payload: id });
  }, []);

  const reset = useCallback(() => {
    dispatch({ type: 'RESET' });
    currentThinkingId.current = null;
    currentAgentName.current = null;
  }, []);

  // ============ Thinking State Management ============

  const setCurrentAgentName = useCallback((name: string | null) => {
    currentAgentName.current = name;
  }, []);

  const getCurrentAgentName = useCallback(() => {
    return currentAgentName.current;
  }, []);

  const setCurrentThinkingId = useCallback((id: string | null) => {
    currentThinkingId.current = id;
  }, []);

  const getCurrentThinkingId = useCallback(() => {
    return currentThinkingId.current;
  }, []);

  // ============ Computed Values ============

  const treeNodes = useMemo(() => {
    if (!state.agentTree?.nodes) return [];
    return buildAgentTree(state.agentTree.nodes);
  }, [state.agentTree?.nodes]);

  const filteredLogs = useMemo(() => {
    return filterLogsByAgent(
      state.logs,
      state.selectedAgentId,
      treeNodes,
      state.showAllLogs
    );
  }, [state.logs, state.selectedAgentId, treeNodes, state.showAllLogs]);

  const isRunning = useMemo(() => {
    return state.task?.status === 'running' || state.task?.status === 'pending';
  }, [state.task?.status]);

  const isComplete = useMemo(() => {
    const status = state.task?.status;
    return status === 'completed' || status === 'failed' || status === 'cancelled';
  }, [state.task?.status]);

  return {
    // State
    ...state,
    treeNodes,
    filteredLogs,
    isRunning,
    isComplete,

    // Actions
    setTask,
    setFindings,
    setAgentTree,
    addLog,
    updateLog,
    removeLog,
    selectAgent,
    toggleShowAllLogs,
    setLoading,
    setError,
    setConnectionStatus,
    setAutoScroll,
    toggleLogExpanded,
    reset,

    // Thinking state
    setCurrentAgentName,
    getCurrentAgentName,
    setCurrentThinkingId,
    getCurrentThinkingId,

    // Direct dispatch for complex operations
    dispatch,
  };
}

export type AgentAuditStateHook = ReturnType<typeof useAgentAuditState>;
