/**
 * WorkspaceViewer — 工作空间浏览器
 *
 * 展示当前工作空间的：
 * - 根路径（可在文件管理器中打开）
 * - 2 个核心文件（SOUL/MEMORY）：状态、大小、修改时间、内容预览
 * - 自动目录（logs/.metona）：存在性和文件数
 *
 * Agent 完成任务后自动刷新（thinking/executing → idle）。
 */

import { useState, useEffect, useRef, useCallback } from 'react';
import {
  Box, Typography, Stack, Accordion, AccordionSummary, AccordionDetails,
  IconButton, Chip, Alert, Tooltip, Divider,
} from '@mui/material';
import { FolderOpen, RefreshCw, ChevronDown, FileText, Folder, CheckCircle2, XCircle } from 'lucide-react';
import { useAgentStore } from '@renderer/stores/agent-store';
import { formatTime, formatFileSize } from '@renderer/lib/formatters';

// ===== 主组件 =====

export function WorkspaceViewer(): React.JSX.Element {
  const [info, setInfo] = useState<MetonaWorkspaceInfo | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);

  // Agent 完成时自动刷新
  const agentStatus = useAgentStore((s) => s.agentStatus);
  const prevStatus = useRef(agentStatus);
  // M-52 修复: 竞态保护 ref，防止多次 loadInfo 调用乱序完成导致旧数据覆盖
  const loadReqIdRef = useRef(0);

  const loadInfo = useCallback(async () => {
    if (!window.metona?.workspace?.getInfo) return;
    const reqId = ++loadReqIdRef.current;
    setLoading(true);
    setError(null);
    try {
      const res = await window.metona.workspace.getInfo();
      // 竞态保护：若已被新请求取代或组件已卸载，放弃本次结果
      if (loadReqIdRef.current !== reqId) return;
      setInfo(res);
    } catch (err) {
      if (loadReqIdRef.current !== reqId) return;
      setError((err as Error).message ?? '加载工作空间信息失败');
    } finally {
      if (loadReqIdRef.current === reqId) setLoading(false);
    }
  }, []);

  // 初次挂载加载
  useEffect(() => {
    loadInfo();
    // cleanup: 使当前请求失效（防止卸载后 setState）
    return () => { loadReqIdRef.current++; };
  }, [loadInfo]);

  // Agent 完成自动刷新
  useEffect(() => {
    const prev = prevStatus.current;
    prevStatus.current = agentStatus;
    if ((prev === 'thinking' || prev === 'executing') && agentStatus === 'idle') {
      loadInfo();
    }
  }, [agentStatus, loadInfo]);

  const handleOpenInFolder = async (path: string) => {
    try {
      await window.metona?.app?.showItemInFolder(path);
    } catch (err) {
      console.error('[WorkspaceViewer]', err);
      import('@metona-team/metona-toast').then((mod) => mod.default.error('打开文件夹失败')).catch(() => {});
    }
  };

  if (error) {
    return <Alert severity="error" sx={{ m: 1 }}>{error}</Alert>;
  }

  if (!info) {
    return <Typography variant="body2" color="text.secondary" sx={{ p: 2 }}>{loading ? '加载中...' : '无数据'}</Typography>;
  }

  return (
    <Stack spacing={1.5} sx={{ flex: 1, overflow: 'auto', minHeight: 0 }}>
      {/* 工作空间根路径 */}
      <Box>
        <Stack direction="row" sx={{ mb: 0.5, alignItems: 'center', justifyContent: 'space-between' }}>
          <Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600 }}>
            当前工作空间
          </Typography>
          <Tooltip title="刷新">
            <IconButton size="small" onClick={loadInfo} disabled={loading} sx={{ p: 0.3 }}>
              <RefreshCw size={13} className={loading ? 'animate-spin' : ''} />
            </IconButton>
          </Tooltip>
        </Stack>
        <Stack direction="row" spacing={0.5} sx={{ flexWrap: 'wrap', alignItems: 'center' }}>
          <Typography
            variant="body2"
            sx={{
              fontFamily: 'monospace',
              fontSize: 11,
              color: 'text.primary',
              wordBreak: 'break-all',
              flex: 1,
            }}
          >
            {info.path}
          </Typography>
          <Tooltip title="在文件管理器中打开">
            <IconButton size="small" onClick={() => handleOpenInFolder(info.path)} sx={{ p: 0.3 }}>
              <FolderOpen size={13} />
            </IconButton>
          </Tooltip>
        </Stack>
      </Box>

      <Divider />

      {/* 核心文件 */}
      <Box>
        <Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600, mb: 0.5, display: 'block' }}>
          核心文件（{info.files.filter((f) => f.exists).length}/{info.files.length}）
        </Typography>
        <Stack spacing={0.5}>
          {info.files.map((file) => (
            <Accordion
              key={file.name}
              disableGutters
              sx={{
                bgcolor: 'background.default',
                '&:before': { display: 'none' },
                border: 1,
                borderColor: 'divider',
                borderRadius: 1,
                overflow: 'hidden',
              }}
            >
              <AccordionSummary expandIcon={<ChevronDown size={14} />} sx={{ minHeight: 32, '& .MuiAccordionSummary-content': { my: 0, alignItems: 'center' } }}>
                <Stack direction="row" spacing={0.5} sx={{ flex: 1, mr: 1, alignItems: 'center' }}>
                  {file.exists ? (
                    <CheckCircle2 size={12} color="var(--mui-palette-success-main)" />
                  ) : (
                    <XCircle size={12} color="var(--mui-palette-error-main)" />
                  )}
                  <Typography variant="caption" sx={{ fontFamily: 'monospace', fontWeight: 600 }}>
                    {file.name}
                  </Typography>
                  {file.exists && (
                    <Typography variant="caption" color="text.secondary" sx={{ ml: 'auto', fontSize: 10 }}>
                      {formatFileSize(file.size)} · {formatTime(file.mtime)}
                    </Typography>
                  )}
                </Stack>
              </AccordionSummary>
              <AccordionDetails sx={{ p: 1, pt: 0 }}>
                {file.exists ? (
                  <Box
                    component="pre"
                    sx={{
                      fontFamily: 'monospace',
                      fontSize: 10,
                      color: 'text.primary',
                      whiteSpace: 'pre-wrap',
                      wordBreak: 'break-word',
                      margin: 0,
                      maxHeight: 200,
                      overflow: 'auto',
                      p: 0.5,
                      bgcolor: 'background.paper',
                      borderRadius: 0.5,
                    }}
                  >
                    {file.preview || '（空文件）'}
                  </Box>
                ) : (
                  <Typography variant="caption" color="error.main">
                    文件不存在
                  </Typography>
                )}
                <Stack direction="row" spacing={0.5} sx={{ mt: 0.5 }}>
                  <Tooltip title="在文件管理器中显示">
                    <IconButton size="small" onClick={() => handleOpenInFolder(file.path)} sx={{ p: 0.3 }}>
                      <FolderOpen size={11} />
                    </IconButton>
                  </Tooltip>
                </Stack>
              </AccordionDetails>
            </Accordion>
          ))}
        </Stack>
      </Box>

      <Divider />

      {/* 自动目录 */}
      <Box>
        <Typography variant="caption" color="text.secondary" sx={{ fontWeight: 600, mb: 0.5, display: 'block' }}>
          自动目录
        </Typography>
        <Stack spacing={0.5}>
          {info.dirs.map((dir) => (
            <Stack
              key={dir.name}
              direction="row"
              spacing={0.5}
              sx={{
                p: 0.5,
                border: 1,
                borderColor: 'divider',
                borderRadius: 1,
                bgcolor: 'background.default',
                alignItems: 'center',
              }}
            >
              <Folder size={12} color={dir.exists ? 'var(--mui-palette-info-main)' : 'var(--mui-palette-text-disabled)'} />
              <Typography variant="caption" sx={{ fontFamily: 'monospace', fontWeight: 600 }}>
                {dir.name}/
              </Typography>
              <Chip
                label={dir.exists ? `${dir.fileCount} 个文件` : '不存在'}
                size="small"
                color={dir.exists ? 'default' : 'error'}
                variant="outlined"
                sx={{ height: 16, fontSize: 9 }}
              />
              <Box sx={{ flex: 1 }} />
              {dir.exists && (
                <Tooltip title="在文件管理器中打开">
                  <IconButton size="small" onClick={() => handleOpenInFolder(dir.path)} sx={{ p: 0.3 }}>
                    <FolderOpen size={11} />
                  </IconButton>
                </Tooltip>
              )}
            </Stack>
          ))}
        </Stack>
      </Box>
    </Stack>
  );
}
