'use client';

import { useState, useEffect, useCallback } from 'react';
import { PageContainer } from '@/components/layout';
import { snapshotApi } from '@/infrastructure/api/snapshot.api';
import { useSnapshotPolling } from '@/hooks/useSnapshotPolling';
import type {
  BackupTarget,
  StorageType,
  SnapshotTask,
  CreateSnapshotDto,
  SnapshotStatus,
} from '@/types/snapshot.types';
import { BACKUP_TARGET_LABELS } from '@/types/snapshot.types';
import styles from './page.module.scss';

function formatBytes(bytes: string | number): string {
  const b = typeof bytes === 'string' ? parseInt(bytes, 10) : bytes;
  if (b === 0) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(b) / Math.log(1024));
  return `${(b / Math.pow(1024, i)).toFixed(2)} ${units[i]}`;
}

function formatDuration(ms: number): string {
  const seconds = Math.floor(ms / 1000);
  const m = Math.floor(seconds / 60);
  const s = seconds % 60;
  return m > 0 ? `${m}分${s}秒` : `${s}秒`;
}

function formatTime(iso: string | null): string {
  if (!iso) return '-';
  return new Date(iso).toLocaleString('zh-CN');
}

function statusLabel(status: SnapshotStatus): string {
  const map: Record<SnapshotStatus, string> = {
    PENDING: '等待中',
    RUNNING: '执行中',
    COMPLETED: '已完成',
    FAILED: '失败',
  };
  return map[status] || status;
}

function statusColor(status: SnapshotStatus): string {
  const map: Record<SnapshotStatus, string> = {
    PENDING: '#999',
    RUNNING: '#1890ff',
    COMPLETED: '#52c41a',
    FAILED: '#ff4d4f',
  };
  return map[status] || '#999';
}

export default function SnapshotsPage() {
  // 可用目标
  const [availableTargets, setAvailableTargets] = useState<BackupTarget[]>([]);
  const [isServiceRunning, setIsServiceRunning] = useState(false);

  // 表单状态
  const [storageType, setStorageType] = useState<StorageType>('MINIO');
  const [storagePath, setStoragePath] = useState('');
  const [selectedTargets, setSelectedTargets] = useState<BackupTarget[]>([]);
  const [isSubmitting, setIsSubmitting] = useState(false);

  // 当前执行中的任务
  const [activeTaskId, setActiveTaskId] = useState<string | null>(null);
  const { progresses, taskCompleted, totalSize, duration } =
    useSnapshotPolling(activeTaskId);

  // 历史列表
  const [tasks, setTasks] = useState<SnapshotTask[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);

  // 加载可用目标
  useEffect(() => {
    snapshotApi
      .getTargets()
      .then((res) => {
        setAvailableTargets(res.targets as BackupTarget[]);
        setSelectedTargets(res.targets as BackupTarget[]);
        setIsServiceRunning(res.isRunning);
      })
      .catch(console.error);
  }, []);

  // 加载历史列表
  const loadHistory = useCallback(() => {
    snapshotApi
      .list(page, 10)
      .then((res) => {
        setTasks(res.tasks);
        setTotal(res.total);
      })
      .catch(console.error);
  }, [page]);

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

  // 任务完成后刷新列表
  useEffect(() => {
    if (taskCompleted) {
      loadHistory();
      setIsServiceRunning(false);
    }
  }, [taskCompleted, loadHistory]);

  // 默认 MinIO 路径
  useEffect(() => {
    if (storageType === 'MINIO' && !storagePath) {
      const date = new Date().toISOString().split('T')[0];
      setStoragePath(`snapshots/${date}`);
    }
  }, [storageType, storagePath]);

  // 开始备份
  const handleStart = async () => {
    if (selectedTargets.length === 0) return;
    setIsSubmitting(true);

    try {
      const dto: CreateSnapshotDto = {
        storageType,
        storagePath: storageType === 'LOCAL' ? 'local' : storagePath,
        targets: selectedTargets,
      };
      const res = await snapshotApi.create(dto);
      setActiveTaskId(res.taskId);
      setIsServiceRunning(true);
    } catch (err: any) {
      alert(err.message || '创建备份任务失败');
    } finally {
      setIsSubmitting(false);
    }
  };

  // 切换目标选择
  const toggleTarget = (target: BackupTarget) => {
    setSelectedTargets((prev) =>
      prev.includes(target) ? prev.filter((t) => t !== target) : [...prev, target],
    );
  };

  // 全选/取消全选
  const toggleAll = () => {
    if (selectedTargets.length === availableTargets.length) {
      setSelectedTargets([]);
    } else {
      setSelectedTargets([...availableTargets]);
    }
  };

  // 删除备份
  const handleDelete = async (id: string) => {
    if (!confirm('确定删除该备份？文件将被永久删除。')) return;
    try {
      await snapshotApi.delete(id);
      loadHistory();
    } catch (err: any) {
      alert(err.message || '删除失败');
    }
  };

  return (
    <PageContainer title="数据快照">
      <div className={styles.container}>

      {/* 创建备份表单 */}
      <div className={styles.card}>
        <h2 className={styles.cardTitle}>创建备份</h2>

        <div className={styles.formGroup}>
          <label className={styles.label}>存储方式</label>
          <div className={styles.radioGroup}>
            <label className={styles.radio}>
              <input
                type="radio"
                checked={storageType === 'MINIO'}
                onChange={() => setStorageType('MINIO')}
                disabled={isServiceRunning}
              />
              MinIO 对象存储
            </label>
            <label className={styles.radio}>
              <input
                type="radio"
                checked={storageType === 'LOCAL'}
                onChange={() => setStorageType('LOCAL')}
                disabled={isServiceRunning}
              />
              服务器临时目录 (可下载)
            </label>
          </div>
        </div>

        {storageType === 'MINIO' && (
          <div className={styles.formGroup}>
            <label className={styles.label}>MinIO 存储路径</label>
            <input
              type="text"
              className={styles.input}
              value={storagePath}
              onChange={(e) => setStoragePath(e.target.value)}
              placeholder="snapshots/2026-02-23"
              disabled={isServiceRunning}
            />
          </div>
        )}

        <div className={styles.formGroup}>
          <label className={styles.label}>
            备份目标
            <button type="button" className={styles.selectAllBtn} onClick={toggleAll} disabled={isServiceRunning}>
              {selectedTargets.length === availableTargets.length ? '取消全选' : '全选'}
            </button>
          </label>
          <div className={styles.checkboxGroup}>
            {availableTargets.map((target) => (
              <label key={target} className={styles.checkbox}>
                <input
                  type="checkbox"
                  checked={selectedTargets.includes(target)}
                  onChange={() => toggleTarget(target)}
                  disabled={isServiceRunning}
                />
                {BACKUP_TARGET_LABELS[target] || target}
              </label>
            ))}
          </div>
        </div>

        <button
          className={styles.startBtn}
          onClick={handleStart}
          disabled={isSubmitting || isServiceRunning || selectedTargets.length === 0}
        >
          {isServiceRunning ? '备份执行中...' : '开始备份'}
        </button>
      </div>

      {/* 实时进度 */}
      {activeTaskId && progresses.size > 0 && (
        <div className={styles.card}>
          <h2 className={styles.cardTitle}>备份进度</h2>

          <div className={styles.progressList}>
            {Array.from(progresses.values()).map((p) => (
              <div key={p.target} className={styles.progressItem}>
                <div className={styles.progressHeader}>
                  <span className={styles.progressTarget}>
                    {BACKUP_TARGET_LABELS[p.target] || p.target}
                  </span>
                  <span style={{ color: statusColor(p.status.toUpperCase() as SnapshotStatus) }}>
                    {p.status === 'completed' ? '100%' : p.status === 'failed' ? '失败' : `${p.percent.toFixed(1)}%`}
                  </span>
                </div>
                <div className={styles.progressBar}>
                  <div
                    className={styles.progressFill}
                    style={{
                      width: `${p.percent}%`,
                      backgroundColor:
                        p.status === 'failed' ? '#ff4d4f' : p.status === 'completed' ? '#52c41a' : '#1890ff',
                    }}
                  />
                </div>
                <div className={styles.progressMsg}>{p.message}</div>
              </div>
            ))}
          </div>

          {taskCompleted && (
            <div className={styles.completedInfo}>
              备份完成！总大小: {formatBytes(totalSize || '0')}，耗时: {formatDuration(duration || 0)}
            </div>
          )}
        </div>
      )}

      {/* 历史备份列表 */}
      <div className={styles.card}>
        <h2 className={styles.cardTitle}>历史备份</h2>

        <div className={styles.tableWrapper}>
          <table className={styles.table}>
            <thead>
              <tr>
                <th>时间</th>
                <th>备份目标</th>
                <th>大小</th>
                <th>存储方式</th>
                <th>状态</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody>
              {tasks.length === 0 && (
                <tr>
                  <td colSpan={6} className={styles.empty}>暂无备份记录</td>
                </tr>
              )}
              {tasks.map((task) => (
                <tr key={task.id}>
                  <td>{formatTime(task.createdAt)}</td>
                  <td>{task.targets.map((t) => BACKUP_TARGET_LABELS[t] || t).join(', ')}</td>
                  <td>{formatBytes(task.totalSize)}</td>
                  <td>{task.storageType === 'MINIO' ? 'MinIO' : '本地'}</td>
                  <td style={{ color: statusColor(task.status) }}>{statusLabel(task.status)}</td>
                  <td>
                    {task.storageType === 'LOCAL' && task.status === 'COMPLETED' && (
                      <>
                        {task.details
                          .filter((d) => d.fileName)
                          .map((d) => (
                            <a
                              key={d.target}
                              href={snapshotApi.getDownloadUrl(task.id, d.target)}
                              className={styles.downloadLink}
                              download
                            >
                              {BACKUP_TARGET_LABELS[d.target]}
                            </a>
                          ))}
                      </>
                    )}
                    <button
                      className={styles.deleteBtn}
                      onClick={() => handleDelete(task.id)}
                    >
                      删除
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        {total > 10 && (
          <div className={styles.pagination}>
            <button disabled={page <= 1} onClick={() => setPage(page - 1)}>上一页</button>
            <span>第 {page} 页 / 共 {Math.ceil(total / 10)} 页</span>
            <button disabled={page >= Math.ceil(total / 10)} onClick={() => setPage(page + 1)}>下一页</button>
          </div>
        )}
      </div>
      </div>
    </PageContainer>
  );
}
