import { useState, useCallback, useEffect, useRef } from 'react';
import agentService from '@/services/agent_service';
import type { IAgent, IGraph } from '@/interfaces/database/agent';
import type { IAgentPaginationParams, IAgentCreateRequestBody, IAgentSettingRequestBody } from '@/interfaces/request/agent';
import logger from '@/utils/logger';
import { useTranslation } from 'react-i18next';
import { useSnackbar } from '@/hooks/useSnackbar';

export interface UseAgentListState {
  agents: IAgent[];
  total: number;
  loading: boolean;
  error: string | null;
  currentPage: number;
  pageSize: number;
  keywords: string;
  orderby?: string;
  desc?: boolean;
}

export interface UseAgentListReturn extends UseAgentListState {
  fetchAgents: (params?: IAgentPaginationParams) => Promise<void>;
  setKeywords: (keywords: string) => void;
  setCurrentPage: (page: number) => void;
  setPageSize: (size: number) => void;
  setOrder: (orderby?: string, desc?: boolean) => void;
  refresh: () => Promise<void>;
}

/**
 * 智能体列表钩子
 * @param initialParams 初始参数
 */
export const useAgentList = (initialParams?: IAgentPaginationParams) => {
  const [agents, setAgents] = useState<IAgent[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(initialParams?.page || 1);
  const [pageSize, setPageSize] = useState(initialParams?.page_size || 10);
  const [keywords, setKeywords] = useState(initialParams?.keywords || '');

  const fetchAgentList = useCallback(async (params?: IAgentPaginationParams) => {
    setLoading(true);
    setError(null);
    try {
      const envMode = import.meta.env.MODE;
      let response: any = null;
      // if (envMode === 'flask') {
        // response = await agentService.teamlistCanvas(params);
      // } else {
        response = await agentService.listCanvas(params);
      // }
      const res = response.data || {};
      logger.info('useAgentList fetchAgentList', res);
      const data = res.data
      setAgents(data.canvas || []);
      setTotal(data.total || 0);
    } catch (err: any) {
      setError(err.message || 'Failed to fetch agent list');
    } finally {
      setLoading(false);
    }
  }, []);

  const refresh = useCallback(() => fetchAgentList({
    keywords,
    page: currentPage,
    page_size: pageSize,
  }), [keywords, currentPage, pageSize]);

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

  return {
    agents,
    total,
    loading,
    error,
    currentPage,
    pageSize,
    keywords,
    fetchAgents: fetchAgentList,
    setKeywords,
    setCurrentPage,
    setPageSize,
    refresh,
  };
};

export function useAgentOperations() {
  const { t } = useTranslation();
  const { showMessage } = useSnackbar();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const createAgent = useCallback(async (body: IAgentCreateRequestBody) => {
    try {
      setLoading(true);
      setError(null);
      const res = await agentService.setCanvas(body);
      const newId = res?.data?.data?.id || res?.data?.id;
      showMessage.success(t('agent.createAgentSuccess'));
      return { success: true, id: newId } as const;
    } catch (err: any) {
      const errorMessage = err?.response?.data?.message || err?.message || t('agent.createAgentFailed');
      setError(errorMessage);
      showMessage.error(errorMessage);
      return { success: false, error: errorMessage } as const;
    } finally {
      setLoading(false);
    }
  }, [t, showMessage]);

  const editAgent = useCallback(async (data: Partial<IAgentSettingRequestBody>) => {
    try {
      setLoading(true);
      setError(null);
      const res = await agentService.settingAgent(data);
      const code = res?.data?.code;
      if (code === 0) {
        showMessage.success(t('message.updated'));
        return { success: true } as const;
      }
      const msg = res?.data?.message || t('common.operationFailed');
      showMessage.error(msg);
      return { success: false, error: msg } as const;
    } catch (err: any) {
      const errorMessage = err?.response?.data?.message || err?.message || t('common.operationFailed');
      setError(errorMessage);
      showMessage.error(errorMessage);
      return { success: false, error: errorMessage } as const;
    } finally {
      setLoading(false);
    }
  }, [t, showMessage]);

  const deleteAgents = useCallback(async (ids: string[]) => {
    try {
      setLoading(true);
      setError(null);
      const res = await agentService.removeCanvas(ids);
      const code = res?.data?.code;
      if (code === 0) {
        showMessage.success(t('message.deleted'));
        return { success: true } as const;
      }
      const msg = res?.data?.message || t('common.operationFailed');
      showMessage.error(msg);
      return { success: false, error: msg } as const;
    } catch (err: any) {
      const errorMessage = err?.response?.data?.message || err?.message || t('common.operationFailed');
      setError(errorMessage);
      showMessage.error(errorMessage);
      return { success: false, error: errorMessage } as const;
    } finally {
      setLoading(false);
    }
  }, [t, showMessage]);

  const clearError = useCallback(() => setError(null), []);

  return { loading, error, createAgent, editAgent, deleteAgents, clearError };
}

/**
 * 智能体详情钩子：拉取 Canvas 详情并解析出图（nodes/edges）
 */
export function useAgentDetail(id?: string) {
  const [agent, setAgent] = useState<IAgent | null>(null);
  const [graph, setGraph] = useState<IGraph | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const fetchDetail = useCallback(async () => {
    if (!id) {
      setError('Invalid agent id');
      return;
    }
    setLoading(true);
    setError(null);
    try {
      const res = await agentService.getCanvas(id);
      const body = res?.data ?? {};
      // 服务端常见返回结构：{ code, data: { id, title, dsl } }
      const data = (body.data ?? body) as IAgent;
      const dsl = (data as any)?.dsl ?? {};
      const g: IGraph | null = dsl?.graph;
      setAgent(data);
      setGraph(g);
      logger.info('useAgentDetail fetched', { id, title: data?.title, nodes: g?.nodes?.length, edges: g?.edges?.length });
    } catch (err: any) {
      const msg = err?.response?.data?.message || err?.message || 'Failed to fetch agent detail';
      setError(msg);
      logger.error('useAgentDetail error', err);
    } finally {
      setLoading(false);
    }
  }, [id]);

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

  return { agent, graph, loading, error, refresh: fetchDetail } as const;
};

export interface UseAgentCanvasOptions {
  agent?: IAgent | null;
  graph?: IGraph | null;
  onReady?: (api: { fitView: () => void }) => void;
  onAutoSaved?: (date: Date) => void;
  disableNoteClick?: boolean;
}

export function useAgentCanvas({ agent, graph, onReady, onAutoSaved, disableNoteClick = true }: UseAgentCanvasOptions) {
  const [selectedNode, setSelectedNode] = useState<any | null>(null);
  const [hoverNode, setHoverNode] = useState<any | null>(null);
  const [sanitized, setSanitized] = useState<IGraph | null>(null);
  const instRef = ({} as any) as { current?: any };

  const sanitizeGraph = useCallback((g?: IGraph | null): IGraph | null => {
    if (!g) return null;
    const nodes = (g.nodes || []).map((n: any) => ({ ...n, draggable: false, selectable: true }));
    const edges = (g.edges || []).map((e: any) => {
      const { sourceHandle, targetHandle, ...rest } = e || {};
      return { ...rest };
    });
    return { nodes, edges };
  }, []);

  useEffect(() => {
    setSanitized(sanitizeGraph(graph));
  }, [graph, sanitizeGraph]);

  const onInit = useCallback((inst: any) => {
    try {
      (instRef as any).current = inst;
      onReady?.({ fitView: () => inst?.fitView?.({ padding: 0.2 }) });
      inst?.fitView?.({ padding: 0.2 });
    } catch (err) {
      logger.error('useAgentCanvas onInit error', err);
    }
  }, [onReady]);

  const onNodeClick = useCallback((_: any, node: any) => {
    if (disableNoteClick && node?.type === 'noteNode') return;
    setSelectedNode(node);
  }, [disableNoteClick]);

  const onPaneClick = useCallback(() => setSelectedNode(null), []);
  const onNodeMouseEnter = useCallback((_: any, node: any) => setHoverNode(node), []);

  // 30秒自动保存（基于当前画布），确保在卸载与依赖变更时清理定时器
  const autoSaveTimerRef = useRef<number | null>(null);
  useEffect(() => {
    // 清理已有定时器，避免重复
    if (autoSaveTimerRef.current) {
      clearInterval(autoSaveTimerRef.current);
      autoSaveTimerRef.current = null;
    }

    // 数据不完整时不创建定时器（Canvas 不可用或退出）
    if (!agent?.id || !agent?.title || !sanitized) {
      return;
    }

    autoSaveTimerRef.current = window.setInterval(async () => {
      try {
        const payload = {
          id: agent.id,
          title: agent.title,
          dsl: { ...(agent.dsl || {}), graph: sanitized },
        };
        await agentService.setAgentDSL(payload as any);
        onAutoSaved?.(new Date());
      } catch (err) {
        logger.error('autoSave failed', err);
      }
    }, 30000);

    return () => {
      if (autoSaveTimerRef.current) {
        clearInterval(autoSaveTimerRef.current);
        autoSaveTimerRef.current = null;
      }
    };
  }, [agent?.id, agent?.title, agent?.dsl, sanitized, onAutoSaved]);

  return {
    sanitized,
    selectedNode,
    hoverNode,
    onInit,
    onNodeClick,
    onPaneClick,
    onNodeMouseEnter,
  } as const;
}