/**
 * 运维控制面板页面
 *
 * 功能：
 * - 服务器系统资源概况（CPU / 内存 / 磁盘）
 * - 各环境服务状态 + 启停重启按钮
 * - 各环境 Git 状态 + pull / 同步依赖按钮
 * - 各环境 .env 配置查看（敏感值脱敏）
 */

import React, { useEffect, useState, useCallback } from "react";
import {
  Card,
  Row,
  Col,
  Tag,
  Button,
  Space,
  Statistic,
  Progress,
  Modal,
  message,
  Descriptions,
  Spin,
  Tooltip,
  Typography,
  Input,
} from "antd";
import {
  PlayCircleOutlined,
  PauseCircleOutlined,
  ReloadOutlined,
  CloudDownloadOutlined,
  SyncOutlined,
  FileTextOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  ClockCircleOutlined,
  DesktopOutlined,
} from "@ant-design/icons";
import type {
  SystemInfo,
  ServiceStatus,
  GitInfo,
} from "../api/opsPanel";
import {
  fetchSystemInfo,
  fetchServicesStatus,
  fetchGitInfo,
  startService,
  stopService,
  restartService,
  gitPull,
  syncDeps,
  fetchEnvFile,
} from "../api/opsPanel";

const { Text, Title } = Typography;
const { TextArea } = Input;

/* ------------------------------------------------------------------ */
/*  工具函数                                                           */
/* ------------------------------------------------------------------ */

/** 秒数格式化为 "Xd Xh Xm" */
function formatUptime(seconds: number | null): string {
  if (seconds == null) return "-";
  const d = Math.floor(seconds / 86400);
  const h = Math.floor((seconds % 86400) / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  const parts: string[] = [];
  if (d > 0) parts.push(`${d}天`);
  if (h > 0) parts.push(`${h}时`);
  parts.push(`${m}分`);
  return parts.join(" ");
}

/* ------------------------------------------------------------------ */
/*  组件                                                               */
/* ------------------------------------------------------------------ */

const OpsPanel: React.FC = () => {
  const [system, setSystem] = useState<SystemInfo | null>(null);
  const [services, setServices] = useState<ServiceStatus[]>([]);
  const [gitInfos, setGitInfos] = useState<GitInfo[]>([]);
  const [loading, setLoading] = useState(true);
  const [actionLoading, setActionLoading] = useState<Record<string, boolean>>({});
  const [envModalOpen, setEnvModalOpen] = useState(false);
  const [envModalContent, setEnvModalContent] = useState("");
  const [envModalTitle, setEnvModalTitle] = useState("");

  // ---- 数据加载 ----

  const loadAll = useCallback(async () => {
    try {
      const [sys, svc, git] = await Promise.all([
        fetchSystemInfo(),
        fetchServicesStatus(),
        fetchGitInfo(),
      ]);
      setSystem(sys);
      setServices(svc);
      setGitInfos(git);
    } catch {
      message.error("加载运维数据失败");
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadAll();
    const timer = setInterval(loadAll, 15_000);
    return () => clearInterval(timer);
  }, [loadAll]);

  // ---- 操作处理 ----

  const withAction = async (key: string, fn: () => Promise<void>) => {
    setActionLoading((prev) => ({ ...prev, [key]: true }));
    try {
      await fn();
    } finally {
      setActionLoading((prev) => ({ ...prev, [key]: false }));
    }
  };

  const handleStart = (env: string) =>
    withAction(`start-${env}`, async () => {
      const r = await startService(env);
      r.success ? message.success(r.message) : message.warning(r.message);
      await loadAll();
    });

  const handleStop = (env: string) =>
    withAction(`stop-${env}`, async () => {
      const r = await stopService(env);
      r.success ? message.success(r.message) : message.warning(r.message);
      await loadAll();
    });

  const handleRestart = (env: string) =>
    withAction(`restart-${env}`, async () => {
      const r = await restartService(env);
      r.success ? message.success(r.message) : message.warning(r.message);
      await loadAll();
    });

  const handlePull = (env: string) =>
    withAction(`pull-${env}`, async () => {
      const r = await gitPull(env);
      if (r.success) {
        message.success("拉取成功");
        Modal.info({ title: `Git Pull - ${env}`, content: <pre style={{ maxHeight: 300, overflow: "auto", fontSize: 12 }}>{r.output}</pre>, width: 600 });
      } else {
        message.error("拉取失败");
        Modal.error({ title: `Git Pull 失败 - ${env}`, content: <pre style={{ maxHeight: 300, overflow: "auto", fontSize: 12 }}>{r.output}</pre>, width: 600 });
      }
      await loadAll();
    });

  const handleSyncDeps = (env: string) =>
    withAction(`sync-${env}`, async () => {
      const r = await syncDeps(env);
      r.success ? message.success("依赖同步完成") : message.error(r.message);
    });

  const handleViewEnv = async (env: string, label: string) => {
    try {
      const r = await fetchEnvFile(env);
      setEnvModalTitle(`${label} .env 配置`);
      setEnvModalContent(r.content);
      setEnvModalOpen(true);
    } catch {
      message.error("读取配置文件失败");
    }
  };

  // ---- 渲染 ----

  if (loading) {
    return <Spin size="large" style={{ display: "flex", justifyContent: "center", marginTop: 120 }} />;
  }

  return (
    <div>
      <Title level={4} style={{ marginBottom: 16 }}>
        <DesktopOutlined style={{ marginRight: 8 }} />
        运维控制面板
      </Title>

      {/* ---- 系统资源 ---- */}
      {system && (
        <Card size="small" title="服务器资源" style={{ marginBottom: 16 }}>
          <Row gutter={24}>
            <Col span={8}>
              <Statistic title="CPU 使用率" value={system.cpu_percent} suffix="%" />
              <Progress percent={system.cpu_percent} size="small" status={system.cpu_percent > 80 ? "exception" : "normal"} showInfo={false} />
            </Col>
            <Col span={8}>
              <Statistic title="内存" value={system.memory_used_gb} suffix={`/ ${system.memory_total_gb} GB`} precision={1} />
              <Progress percent={system.memory_percent} size="small" status={system.memory_percent > 85 ? "exception" : "normal"} showInfo={false} />
            </Col>
            <Col span={8}>
              <Statistic title="磁盘" value={system.disk_used_gb} suffix={`/ ${system.disk_total_gb} GB`} precision={1} />
              <Progress percent={system.disk_percent} size="small" status={system.disk_percent > 90 ? "exception" : "normal"} showInfo={false} />
            </Col>
          </Row>
          <Text type="secondary" style={{ fontSize: 12, marginTop: 8, display: "block" }}>
            开机时间：{new Date(system.boot_time).toLocaleString()}
          </Text>
        </Card>
      )}

      {/* ---- 服务状态 ---- */}
      <Card size="small" title="服务状态" style={{ marginBottom: 16 }}>
        <Row gutter={16}>
          {services.map((svc) => (
            <Col span={12} key={svc.env}>
              <Card
                size="small"
                type="inner"
                title={
                  <Space>
                    {svc.running
                      ? <CheckCircleOutlined style={{ color: "#52c41a" }} />
                      : <CloseCircleOutlined style={{ color: "#ff4d4f" }} />}
                    {svc.label}
                    <Tag color={svc.running ? "success" : "error"}>
                      {svc.running ? "运行中" : "已停止"}
                    </Tag>
                  </Space>
                }
                extra={<Tag>:{svc.port}</Tag>}
              >
                {svc.running && (
                  <Descriptions size="small" column={3} style={{ marginBottom: 12 }}>
                    <Descriptions.Item label="PID">{svc.pid}</Descriptions.Item>
                    <Descriptions.Item label="运行时长">
                      <ClockCircleOutlined style={{ marginRight: 4 }} />
                      {formatUptime(svc.uptime_seconds)}
                    </Descriptions.Item>
                    <Descriptions.Item label="内存">{svc.memory_mb ?? "-"} MB</Descriptions.Item>
                  </Descriptions>
                )}
                <Space>
                  {!svc.running && (
                    <Button
                      type="primary"
                      size="small"
                      icon={<PlayCircleOutlined />}
                      loading={actionLoading[`start-${svc.env}`]}
                      onClick={() => handleStart(svc.env)}
                    >
                      启动
                    </Button>
                  )}
                  {svc.running && (
                    <>
                      <Button
                        danger
                        size="small"
                        icon={<PauseCircleOutlined />}
                        loading={actionLoading[`stop-${svc.env}`]}
                        onClick={() => handleStop(svc.env)}
                      >
                        停止
                      </Button>
                      <Button
                        size="small"
                        icon={<ReloadOutlined />}
                        loading={actionLoading[`restart-${svc.env}`]}
                        onClick={() => handleRestart(svc.env)}
                      >
                        重启
                      </Button>
                    </>
                  )}
                </Space>
              </Card>
            </Col>
          ))}
        </Row>
      </Card>

      {/* ---- Git 状态 & 配置 ---- */}
      <Card size="small" title="代码与配置" style={{ marginBottom: 16 }}>
        <Row gutter={16}>
          {gitInfos.map((git) => {
            const envCfg = services.find((s) => s.env === git.env);
            const label = envCfg?.label ?? git.env;
            return (
              <Col span={12} key={git.env}>
                <Card size="small" type="inner" title={label}>
                  <Descriptions size="small" column={1} style={{ marginBottom: 12 }}>
                    <Descriptions.Item label="分支">
                      <Tag color="blue">{git.branch}</Tag>
                      {git.has_local_changes && (
                        <Tooltip title="工作区有未提交的变更">
                          <Tag color="warning">有变更</Tag>
                        </Tooltip>
                      )}
                    </Descriptions.Item>
                    <Descriptions.Item label="最新提交">
                      <Text code style={{ fontSize: 12 }}>{git.last_commit_hash}</Text>
                      <Text type="secondary" style={{ marginLeft: 8, fontSize: 12 }}>
                        {git.last_commit_message}
                      </Text>
                    </Descriptions.Item>
                    <Descriptions.Item label="提交时间">
                      <Text type="secondary" style={{ fontSize: 12 }}>{git.last_commit_time}</Text>
                    </Descriptions.Item>
                  </Descriptions>
                  <Space>
                    <Button
                      size="small"
                      icon={<CloudDownloadOutlined />}
                      loading={actionLoading[`pull-${git.env}`]}
                      onClick={() => handlePull(git.env)}
                    >
                      Git Pull
                    </Button>
                    <Button
                      size="small"
                      icon={<SyncOutlined />}
                      loading={actionLoading[`sync-${git.env}`]}
                      onClick={() => handleSyncDeps(git.env)}
                    >
                      同步依赖
                    </Button>
                    <Button
                      size="small"
                      icon={<FileTextOutlined />}
                      onClick={() => handleViewEnv(git.env, label)}
                    >
                      查看配置
                    </Button>
                  </Space>
                </Card>
              </Col>
            );
          })}
        </Row>
      </Card>

      {/* ---- 配置查看弹窗 ---- */}
      <Modal
        title={envModalTitle}
        open={envModalOpen}
        onCancel={() => setEnvModalOpen(false)}
        footer={null}
        width={700}
      >
        <TextArea
          value={envModalContent}
          readOnly
          autoSize={{ minRows: 10, maxRows: 30 }}
          style={{ fontFamily: "monospace", fontSize: 12 }}
        />
      </Modal>
    </div>
  );
};

export default OpsPanel;
