/**
 * 视频编辑功能状态管理Hook
 */

import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
import {
  EditPoint,
  EditPointAction,
  VideoEditContext,
  VideoEditConfig,
  CreateEditPointRequest,
  UpdateEditPointRequest,
  DeleteEditPointRequest,
  EditPointStatus,
  EditPointPosition
} from './types';
import { createEditPoint, updateEditPoint, deleteEditPoint, getEditPoints } from './api';
import { debounce } from './utils';

/**
 * 默认编辑配置 - 更新为匹配参考图像的白色样式
 */
const DEFAULT_CONFIG: VideoEditConfig = {
  enabled: true,
  maxEditPoints: 10,
  connectionStyle: {
    color: 'rgba(255, 255, 255, 0.9)', // 白色连接线匹配参考图像
    strokeWidth: 2,
    dashArray: '8,4' // 虚线样式匹配参考图像
  },
  pointStyle: {
    size: 12,
    color: 'transparent', // 透明编辑点匹配参考图像
    pulseColor: 'transparent' // 透明脉冲动画
  }
};

/**
 * useVideoEdit Hook参数
 */
interface UseVideoEditProps {
  /** 项目ID */
  projectId: string;
  /** 用户ID */
  userId: number;
  /** 当前视频信息 */
  currentVideo?: {
    id: string;
    url: string;
    duration: number;
  } | null;
  /** 编辑配置 */
  config?: Partial<VideoEditConfig>;
  /** 编辑点变化回调 */
  onEditPointsChange?: (editPoints: EditPoint[]) => void;
  /** 编辑描述提交回调 */
  onDescriptionSubmit?: (editPoint: EditPoint, description: string) => void;
}

/**
 * useVideoEdit Hook返回值
 */
interface UseVideoEditReturn {
  /** 编辑上下文 */
  context: VideoEditContext;
  /** 创建编辑点 */
  createEditPoint: (position: EditPointPosition, timestamp: number) => Promise<EditPoint | null>;
  /** 更新编辑点 */
  updateEditPoint: (id: string, updates: Partial<EditPoint>) => Promise<boolean>;
  /** 删除编辑点 */
  deleteEditPoint: (id: string) => Promise<boolean>;
  /** 选择编辑点 */
  selectEditPoint: (id: string | null) => void;
  /** 切换编辑模式 */
  toggleEditMode: (enabled?: boolean) => void;
  /** 显示/隐藏输入框 */
  toggleInput: (id: string, show?: boolean) => void;
  /** 提交编辑描述 */
  submitDescription: (id: string, description: string) => Promise<boolean>;
  /** 刷新编辑点列表 */
  refreshEditPoints: () => Promise<void>;
  /** 清空所有编辑点 */
  clearAllEditPoints: () => Promise<boolean>;
}

/**
 * 视频编辑状态管理Hook
 */
export function useVideoEdit({
  projectId,
  userId,
  currentVideo,
  config = {},
  onEditPointsChange,
  onDescriptionSubmit
}: UseVideoEditProps): UseVideoEditReturn {
  
  // 合并配置
  const mergedConfig = useMemo(() => ({
    ...DEFAULT_CONFIG,
    ...config,
    connectionStyle: { ...DEFAULT_CONFIG.connectionStyle, ...config.connectionStyle },
    pointStyle: { ...DEFAULT_CONFIG.pointStyle, ...config.pointStyle }
  }), [config]);

  // 状态管理
  const [editPoints, setEditPoints] = useState<EditPoint[]>([]);
  const [isEditMode, setIsEditMode] = useState(true);
  const [selectedEditPointId, setSelectedEditPointId] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);

  // 引用
  const editPointsRef = useRef<EditPoint[]>([]);
  const nextIdRef = useRef(1);

  // 同步editPoints到ref
  useEffect(() => {
    editPointsRef.current = editPoints;
  }, [editPoints]);

  // 生成唯一ID
  const generateId = useCallback(() => {
    return `edit-point-${Date.now()}-${nextIdRef.current++}`;
  }, []);

  // 创建编辑上下文
  const context: VideoEditContext = useMemo(() => ({
    currentVideo: currentVideo || null,
    editPoints,
    config: mergedConfig,
    isEditMode,
    selectedEditPointId
  }), [currentVideo, editPoints, mergedConfig, isEditMode, selectedEditPointId]);

  // 创建编辑点
  const handleCreateEditPoint = useCallback(async (
    position: EditPointPosition, 
    timestamp: number
  ): Promise<EditPoint | null> => {
    if (!currentVideo || editPoints.length >= mergedConfig.maxEditPoints) {
      return null;
    }

    const newEditPoint: EditPoint = {
      id: generateId(),
      videoId: currentVideo.id,
      projectId,
      userId,
      position,
      timestamp,
      description: '',
      status: EditPointStatus.PENDING,
      createdAt: Date.now(),
      updatedAt: Date.now(),
      showInput: true,
      connectionDirection: 'auto'
    };

    try {
      setIsLoading(true);
      
      // 先更新本地状态，提供即时反馈
      setEditPoints(prev => [...prev, newEditPoint]);
      setSelectedEditPointId(newEditPoint.id);
      
      // 调用API创建编辑点
      const createdEditPoint = await createEditPoint({
        videoId: currentVideo.id,
        projectId,
        position,
        timestamp,
        description: ''
      });

      if (createdEditPoint) {
        // 更新为服务器返回的数据，但保持输入框显示状态
        const updatedEditPoint: EditPoint = {
          ...createdEditPoint,
          showInput: true, // 确保新创建的编辑点显示输入框
          connectionDirection: 'auto' as const
        };

        setEditPoints(prev =>
          prev.map(point =>
            point.id === newEditPoint.id ? updatedEditPoint : point
          )
        );
        onEditPointsChange?.(editPointsRef.current);
        return updatedEditPoint;
      } else {
        // 创建失败，移除本地添加的点
        setEditPoints(prev => prev.filter(point => point.id !== newEditPoint.id));
        return null;
      }
    } catch (error) {
      console.error('创建编辑点失败:', error);
      // 创建失败，移除本地添加的点
      setEditPoints(prev => prev.filter(point => point.id !== newEditPoint.id));
      return null;
    } finally {
      setIsLoading(false);
    }
  }, [currentVideo, editPoints.length, mergedConfig.maxEditPoints, generateId, projectId, userId, onEditPointsChange]);

  // 更新编辑点
  const handleUpdateEditPoint = useCallback(async (
    id: string, 
    updates: Partial<EditPoint>
  ): Promise<boolean> => {
    try {
      setIsLoading(true);
      
      // 先更新本地状态
      setEditPoints(prev => 
        prev.map(point => 
          point.id === id 
            ? { ...point, ...updates, updatedAt: Date.now() }
            : point
        )
      );

      // 调用API更新
      const success = await updateEditPoint({
        id,
        description: updates.description,
        status: updates.status,
        position: updates.position
      });

      if (success) {
        onEditPointsChange?.(editPointsRef.current);
        return true;
      } else {
        // 更新失败，恢复原状态
        await refreshEditPoints();
        return false;
      }
    } catch (error) {
      console.error('更新编辑点失败:', error);
      // 更新失败，恢复原状态
      await refreshEditPoints();
      return false;
    } finally {
      setIsLoading(false);
    }
  }, [onEditPointsChange]);

  // 删除编辑点
  const handleDeleteEditPoint = useCallback(async (id: string): Promise<boolean> => {
    try {
      setIsLoading(true);
      
      // 先更新本地状态
      const originalEditPoints = editPointsRef.current;
      setEditPoints(prev => prev.filter(point => point.id !== id));
      
      if (selectedEditPointId === id) {
        setSelectedEditPointId(null);
      }

      // 调用API删除
      const success = await deleteEditPoint({ id });

      if (success) {
        onEditPointsChange?.(editPointsRef.current);
        return true;
      } else {
        // 删除失败，恢复原状态
        setEditPoints(originalEditPoints);
        return false;
      }
    } catch (error) {
      console.error('删除编辑点失败:', error);
      // 删除失败，恢复原状态
      await refreshEditPoints();
      return false;
    } finally {
      setIsLoading(false);
    }
  }, [selectedEditPointId, onEditPointsChange]);

  // 选择编辑点
  const selectEditPoint = useCallback((id: string | null) => {
    setSelectedEditPointId(id);
  }, []);

  // 切换编辑模式
  const toggleEditMode = useCallback((enabled?: boolean) => {
    setIsEditMode(prev => enabled !== undefined ? enabled : !prev);
    if (enabled === false) {
      setSelectedEditPointId(null);
    }
  }, []);

  // 显示/隐藏输入框
  const toggleInput = useCallback((id: string, show?: boolean) => {
    setEditPoints(prev => 
      prev.map(point => 
        point.id === id 
          ? { ...point, showInput: show !== undefined ? show : !point.showInput }
          : point
      )
    );
  }, []);

  // 提交编辑描述
  const submitDescription = useCallback(async (id: string, description: string): Promise<boolean> => {
    const editPoint = editPoints.find(point => point.id === id);
    if (!editPoint) return false;

    // 只更新描述和状态，不隐藏输入框（由调用方决定）
    const success = await handleUpdateEditPoint(id, {
      description,
      status: EditPointStatus.EDITED
    });

    if (success && onDescriptionSubmit) {
      const updatedEditPoint = editPointsRef.current.find(point => point.id === id);
      if (updatedEditPoint) {
        onDescriptionSubmit(updatedEditPoint, description);
      }
    }

    return success;
  }, [editPoints, handleUpdateEditPoint, onDescriptionSubmit]);

  // 刷新编辑点列表
  const refreshEditPoints = useCallback(async () => {
    if (!currentVideo) return;

    try {
      setIsLoading(true);
      const response = await getEditPoints({
        videoId: currentVideo.id,
        projectId
      });
      
      if (response) {
        setEditPoints(response.editPoints);
        onEditPointsChange?.(response.editPoints);
      }
    } catch (error) {
      console.error('刷新编辑点列表失败:', error);
    } finally {
      setIsLoading(false);
    }
  }, [currentVideo, projectId, onEditPointsChange]);

  // 清空所有编辑点
  const clearAllEditPoints = useCallback(async (): Promise<boolean> => {
    try {
      setIsLoading(true);
      
      // 批量删除所有编辑点
      const deletePromises = editPoints.map(point => deleteEditPoint({ id: point.id }));
      const results = await Promise.all(deletePromises);
      
      const allSuccess = results.every(result => result);
      
      if (allSuccess) {
        setEditPoints([]);
        setSelectedEditPointId(null);
        onEditPointsChange?.([]);
        return true;
      } else {
        // 部分删除失败，刷新列表
        await refreshEditPoints();
        return false;
      }
    } catch (error) {
      console.error('清空编辑点失败:', error);
      return false;
    } finally {
      setIsLoading(false);
    }
  }, [editPoints, refreshEditPoints, onEditPointsChange]);

  // 当视频变化时，刷新编辑点列表
  useEffect(() => {
    if (currentVideo) {
      refreshEditPoints();
    } else {
      setEditPoints([]);
      setSelectedEditPointId(null);
    }
  }, [currentVideo?.id, refreshEditPoints]);

  return {
    context,
    createEditPoint: handleCreateEditPoint,
    updateEditPoint: handleUpdateEditPoint,
    deleteEditPoint: handleDeleteEditPoint,
    selectEditPoint,
    toggleEditMode,
    toggleInput,
    submitDescription,
    refreshEditPoints,
    clearAllEditPoints
  };
}
