/**
 * IDE Component
 *
 * 整合文件浏览器和代码编辑器的 IDE 组件
 */

import { useState, useCallback, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
import { toast } from 'sonner';
import { cn } from '../utils/cn.js';
import { readFile, getWorkingDirectory } from '../api/client.js';
import { FileExplorer } from './FileExplorer.js';
import { CodeEditor, getLanguageFromFilename, type EditorTab } from './CodeEditor.js';
import { DiffEditor } from './DiffEditor.js';
import type { ActiveFileInfo, FileDiffInfo } from '../api/types.js';

// localStorage 键名
const STORAGE_KEY_TABS = 'ai-assistant-editor-tabs';
const STORAGE_KEY_ACTIVE_TAB = 'ai-assistant-editor-active-tab';

// 保存的标签页格式（只保存路径，不保存内容）
interface SavedTab {
  path: string;
  name: string;
}

interface IDEProps {
  className?: string;
  /** 文件浏览器宽度 */
  sidebarWidth?: number;
  /** 当前活动文件变化回调 */
  onActiveFileChange?: (file: ActiveFileInfo | null) => void;
  /** 要显示的 Diff 信息（外部传入） */
  pendingDiff?: FileDiffInfo | null;
  /** Diff 关闭回调 */
  onDiffClose?: () => void;
}

/** IDE 组件暴露的方法 */
export interface IDEHandle {
  /** 显示文件 diff */
  showDiff: (diff: FileDiffInfo) => void;
  /** 关闭 diff 视图 */
  closeDiff: () => void;
}

export const IDE = forwardRef<IDEHandle, IDEProps>(function IDE(
  { className, sidebarWidth = 256, onActiveFileChange, pendingDiff, onDiffClose },
  ref
) {
  const [tabs, setTabs] = useState<EditorTab[]>([]);
  const [activeTabId, setActiveTabId] = useState<string | null>(null);
  const [workingDirectory, setWorkingDirectory] = useState<string>('');
  const [currentDiff, setCurrentDiff] = useState<FileDiffInfo | null>(null);
  const isRestoringTabs = useRef(false);
  const hasRestoredTabs = useRef(false);

  // 获取工作目录
  useEffect(() => {
    getWorkingDirectory()
      .then((result) => {
        if (result?.data?.workingDirectory) {
          setWorkingDirectory(result.data.workingDirectory);
        }
      })
      .catch(() => {
        // 忽略错误
      });
  }, []);

  // 从 localStorage 恢复标签页
  useEffect(() => {
    if (hasRestoredTabs.current) return;
    hasRestoredTabs.current = true;

    const restoreTabs = async () => {
      try {
        const savedTabsJson = localStorage.getItem(STORAGE_KEY_TABS);
        const savedActivePath = localStorage.getItem(STORAGE_KEY_ACTIVE_TAB);

        if (!savedTabsJson) return;

        const savedTabs: SavedTab[] = JSON.parse(savedTabsJson);
        if (savedTabs.length === 0) return;

        isRestoringTabs.current = true;

        // 逐个恢复标签页
        const restoredTabs: EditorTab[] = [];
        for (const savedTab of savedTabs) {
          try {
            const result = await readFile(savedTab.path);
            if (result.success && result.data.encoding === 'utf-8') {
              restoredTabs.push({
                id: `tab-${Date.now()}-${restoredTabs.length}`,
                path: savedTab.path,
                name: savedTab.name,
                content: result.data.content,
                originalContent: result.data.content,
                language: getLanguageFromFilename(savedTab.name),
              });
            }
          } catch {
            // 文件可能已删除，跳过
          }
        }

        if (restoredTabs.length > 0) {
          setTabs(restoredTabs);

          // 恢复活动标签
          if (savedActivePath) {
            const activeTab = restoredTabs.find((tab) => tab.path === savedActivePath);
            if (activeTab) {
              setActiveTabId(activeTab.id);
            } else {
              setActiveTabId(restoredTabs[0].id);
            }
          } else {
            setActiveTabId(restoredTabs[0].id);
          }
        }

        isRestoringTabs.current = false;
      } catch {
        isRestoringTabs.current = false;
      }
    };

    restoreTabs();
  }, []);

  // 保存标签页到 localStorage
  useEffect(() => {
    // 恢复过程中不保存
    if (isRestoringTabs.current) return;

    const tabsToSave: SavedTab[] = tabs.map((tab) => ({
      path: tab.path,
      name: tab.name,
    }));
    localStorage.setItem(STORAGE_KEY_TABS, JSON.stringify(tabsToSave));
  }, [tabs]);

  // 保存活动标签到 localStorage
  useEffect(() => {
    // 恢复过程中不保存
    if (isRestoringTabs.current) return;

    const activeTab = tabs.find((tab) => tab.id === activeTabId);
    if (activeTab) {
      localStorage.setItem(STORAGE_KEY_ACTIVE_TAB, activeTab.path);
    } else {
      localStorage.removeItem(STORAGE_KEY_ACTIVE_TAB);
    }
  }, [activeTabId, tabs]);

  // 通知父组件活动文件变化
  useEffect(() => {
    if (!onActiveFileChange) return;

    const activeTab = tabs.find((tab) => tab.id === activeTabId);
    if (activeTab) {
      onActiveFileChange({
        path: activeTab.path,
        name: activeTab.name,
        content: activeTab.content,
        language: activeTab.language,
      });
    } else {
      onActiveFileChange(null);
    }
  }, [activeTabId, tabs, onActiveFileChange]);

  // 打开文件
  const handleFileSelect = useCallback(async (path: string, name: string) => {
    // 检查是否已打开
    const existingTab = tabs.find((tab) => tab.path === path);
    if (existingTab) {
      setActiveTabId(existingTab.id);
      return;
    }

    // 读取文件内容
    try {
      const result = await readFile(path);
      if (result.success && result.data.encoding === 'utf-8') {
        const newTab: EditorTab = {
          id: `tab-${Date.now()}`,
          path,
          name,
          content: result.data.content,
          originalContent: result.data.content,
          language: getLanguageFromFilename(name),
        };
        setTabs((prev) => [...prev, newTab]);
        setActiveTabId(newTab.id);
      } else if (result.data.encoding === 'base64') {
        toast.error('Cannot edit binary files');
      } else {
        toast.error('Failed to open file');
      }
    } catch (error) {
      console.error('Failed to open file:', error);
      toast.error('Failed to open file');
    }
  }, [tabs]);

  // 切换标签
  const handleTabChange = useCallback((tabId: string) => {
    setActiveTabId(tabId);
  }, []);

  // 关闭标签
  const handleTabClose = useCallback((tabId: string) => {
    const tabIndex = tabs.findIndex((tab) => tab.id === tabId);
    const tab = tabs[tabIndex];

    // 检查是否有未保存的更改
    if (tab && tab.content !== tab.originalContent) {
      const confirmed = window.confirm(`${tab.name} has unsaved changes. Close anyway?`);
      if (!confirmed) return;
    }

    setTabs((prev) => prev.filter((tab) => tab.id !== tabId));

    // 如果关闭的是当前标签，切换到相邻标签
    if (activeTabId === tabId) {
      if (tabs.length > 1) {
        const newIndex = tabIndex === 0 ? 1 : tabIndex - 1;
        setActiveTabId(tabs[newIndex].id);
      } else {
        setActiveTabId(null);
      }
    }
  }, [tabs, activeTabId]);

  // 内容更改
  const handleContentChange = useCallback((tabId: string, content: string) => {
    setTabs((prev) =>
      prev.map((tab) =>
        tab.id === tabId ? { ...tab, content } : tab
      )
    );
  }, []);

  // 保存后更新原始内容
  const handleSave = useCallback((tabId: string, _path: string, content: string) => {
    setTabs((prev) =>
      prev.map((tab) =>
        tab.id === tabId ? { ...tab, originalContent: content } : tab
      )
    );
  }, []);

  // 显示 diff 视图
  const showDiff = useCallback((diff: FileDiffInfo) => {
    setCurrentDiff(diff);

    // 如果文件已在编辑器中打开，更新其内容
    setTabs((prev) =>
      prev.map((tab) => {
        if (tab.path === diff.path) {
          return {
            ...tab,
            content: diff.newContent,
            originalContent: diff.newContent,
          };
        }
        return tab;
      })
    );
  }, []);

  // 关闭 diff 视图
  const closeDiff = useCallback(() => {
    setCurrentDiff(null);
    onDiffClose?.();
  }, [onDiffClose]);

  // 暴露方法给父组件
  useImperativeHandle(ref, () => ({
    showDiff,
    closeDiff,
  }), [showDiff, closeDiff]);

  // 处理外部传入的 pendingDiff
  useEffect(() => {
    if (pendingDiff) {
      showDiff(pendingDiff);
    }
  }, [pendingDiff, showDiff]);

  // 判断是否显示 diff 视图
  const showDiffView = currentDiff !== null;

  return (
    <div className={cn('flex h-full', className)}>
      {/* 文件浏览器 */}
      <div
        className="flex-shrink-0 border-r border-line"
        style={{ width: sidebarWidth }}
      >
        <FileExplorer onFileSelect={handleFileSelect} workingDirectory={workingDirectory} />
      </div>

      {/* 代码编辑器 / Diff 视图 */}
      <div className="flex-1 min-w-0">
        {showDiffView ? (
          <DiffEditor
            diff={currentDiff}
            onClose={closeDiff}
          />
        ) : (
          <CodeEditor
            tabs={tabs}
            activeTabId={activeTabId}
            onTabChange={handleTabChange}
            onTabClose={handleTabClose}
            onContentChange={handleContentChange}
            onSave={handleSave}
          />
        )}
      </div>
    </div>
  );
});
