'use client';

import { useState, useEffect, useCallback } from 'react';
import { snapshotApi } from '@/lib/api/snapshot.api';
import { useSnapshotPolling } from '@/lib/hooks/useSnapshotPolling';
import type {
  BackupTarget,
  StorageType,
  SnapshotTask,
  CreateSnapshotDto,
  SnapshotStatus,
} from '@/types/snapshot.types';
import { BACKUP_TARGET_LABELS } from '@/types/snapshot.types';

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');
}

const STATUS_MAP: Record<SnapshotStatus, { label: string; color: string }> = {
  PENDING: { label: '等待中', color: 'text-muted-foreground' },
  RUNNING: { label: '执行中', color: 'text-blue-500' },
  COMPLETED: { label: '已完成', color: 'text-green-500' },
  FAILED: { label: '失败', color: 'text-red-500' },
};

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]);

  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 = () => {
    setSelectedTargets(
      selectedTargets.length === availableTargets.length ? [] : [...availableTargets],
    );
  };

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

  return (
    <div className="space-y-6">
      <h1 className="text-2xl font-semibold text-foreground">数据快照</h1>

      {/* 创建备份 */}
      <div className="rounded-xl border bg-card p-6 shadow-sm">
        <h2 className="mb-4 text-lg font-semibold">创建备份</h2>

        <div className="mb-4">
          <label className="mb-2 block text-sm font-medium">存储方式</label>
          <div className="flex gap-6">
            <label className="flex cursor-pointer items-center gap-2 text-sm">
              <input
                type="radio"
                className="accent-primary"
                checked={storageType === 'MINIO'}
                onChange={() => setStorageType('MINIO')}
                disabled={isServiceRunning}
              />
              MinIO 对象存储
            </label>
            <label className="flex cursor-pointer items-center gap-2 text-sm">
              <input
                type="radio"
                className="accent-primary"
                checked={storageType === 'LOCAL'}
                onChange={() => setStorageType('LOCAL')}
                disabled={isServiceRunning}
              />
              服务器临时目录 (可下载)
            </label>
          </div>
        </div>

        {storageType === 'MINIO' && (
          <div className="mb-4">
            <label className="mb-2 block text-sm font-medium">MinIO 存储路径</label>
            <input
              type="text"
              className="w-full max-w-md rounded-lg border bg-background px-3 py-2 text-sm outline-none focus:border-primary"
              value={storagePath}
              onChange={(e) => setStoragePath(e.target.value)}
              placeholder="snapshots/2026-02-23"
              disabled={isServiceRunning}
            />
          </div>
        )}

        <div className="mb-4">
          <label className="mb-2 flex items-center gap-2 text-sm font-medium">
            备份目标
            <button
              type="button"
              className="text-xs text-primary hover:underline disabled:text-muted-foreground"
              onClick={toggleAll}
              disabled={isServiceRunning}
            >
              {selectedTargets.length === availableTargets.length ? '取消全选' : '全选'}
            </button>
          </label>
          <div className="flex flex-wrap gap-3">
            {availableTargets.map((target) => (
              <label
                key={target}
                className="flex cursor-pointer items-center gap-2 rounded-lg bg-muted px-3 py-2 text-sm transition-colors hover:bg-muted/80"
              >
                <input
                  type="checkbox"
                  className="accent-primary"
                  checked={selectedTargets.includes(target)}
                  onChange={() => toggleTarget(target)}
                  disabled={isServiceRunning}
                />
                {BACKUP_TARGET_LABELS[target] || target}
              </label>
            ))}
          </div>
        </div>

        <button
          className="rounded-lg bg-primary px-8 py-2.5 text-sm font-medium text-primary-foreground transition-colors hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-50"
          onClick={handleStart}
          disabled={isSubmitting || isServiceRunning || selectedTargets.length === 0}
        >
          {isServiceRunning ? '备份执行中...' : '开始备份'}
        </button>
      </div>

      {/* 实时进度 */}
      {activeTaskId && progresses.size > 0 && (
        <div className="rounded-xl border bg-card p-6 shadow-sm">
          <h2 className="mb-4 text-lg font-semibold">备份进度</h2>

          <div className="space-y-4">
            {Array.from(progresses.values()).map((p) => (
              <div key={p.target} className="rounded-lg bg-muted/50 p-4">
                <div className="mb-2 flex items-center justify-between text-sm">
                  <span className="font-medium">{BACKUP_TARGET_LABELS[p.target] || p.target}</span>
                  <span
                    className={
                      p.status === 'completed'
                        ? 'text-green-500'
                        : p.status === 'failed'
                          ? 'text-red-500'
                          : 'text-blue-500'
                    }
                  >
                    {p.status === 'completed' ? '100%' : p.status === 'failed' ? '失败' : `${p.percent.toFixed(1)}%`}
                  </span>
                </div>
                <div className="h-2 overflow-hidden rounded-full bg-muted">
                  <div
                    className="h-full rounded-full transition-all duration-300"
                    style={{
                      width: `${p.percent}%`,
                      backgroundColor:
                        p.status === 'failed' ? '#ef4444' : p.status === 'completed' ? '#22c55e' : '#3b82f6',
                    }}
                  />
                </div>
                <p className="mt-1 text-xs text-muted-foreground">{p.message}</p>
              </div>
            ))}
          </div>

          {taskCompleted && (
            <div className="mt-4 rounded-lg border border-green-200 bg-green-50 p-4 text-sm font-medium text-green-600">
              备份完成！总大小: {formatBytes(totalSize || '0')}，耗时: {formatDuration(duration || 0)}
            </div>
          )}
        </div>
      )}

      {/* 历史列表 */}
      <div className="rounded-xl border bg-card p-6 shadow-sm">
        <h2 className="mb-4 text-lg font-semibold">历史备份</h2>

        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead>
              <tr className="border-b text-left text-muted-foreground">
                <th className="px-3 py-3 font-medium">时间</th>
                <th className="px-3 py-3 font-medium">备份目标</th>
                <th className="px-3 py-3 font-medium">大小</th>
                <th className="px-3 py-3 font-medium">存储方式</th>
                <th className="px-3 py-3 font-medium">状态</th>
                <th className="px-3 py-3 font-medium">操作</th>
              </tr>
            </thead>
            <tbody>
              {tasks.length === 0 && (
                <tr>
                  <td colSpan={6} className="py-8 text-center text-muted-foreground">暂无备份记录</td>
                </tr>
              )}
              {tasks.map((task) => {
                const st = STATUS_MAP[task.status];
                return (
                  <tr key={task.id} className="border-b last:border-0 hover:bg-muted/30">
                    <td className="px-3 py-3">{formatTime(task.createdAt)}</td>
                    <td className="px-3 py-3">
                      {task.targets.map((t) => BACKUP_TARGET_LABELS[t] || t).join(', ')}
                    </td>
                    <td className="px-3 py-3">{formatBytes(task.totalSize)}</td>
                    <td className="px-3 py-3">{task.storageType === 'MINIO' ? 'MinIO' : '本地'}</td>
                    <td className={`px-3 py-3 ${st.color}`}>{st.label}</td>
                    <td className="px-3 py-3">
                      {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="mr-2 text-primary hover:underline"
                              download
                            >
                              {BACKUP_TARGET_LABELS[d.target]}
                            </a>
                          ))}
                      <button
                        className="text-red-500 hover:underline"
                        onClick={() => handleDelete(task.id)}
                      >
                        删除
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {total > 10 && (
          <div className="mt-4 flex items-center justify-center gap-4 text-sm">
            <button
              className="rounded border px-3 py-1 hover:border-primary hover:text-primary disabled:cursor-not-allowed disabled:text-muted-foreground"
              disabled={page <= 1}
              onClick={() => setPage(page - 1)}
            >
              上一页
            </button>
            <span className="text-muted-foreground">
              第 {page} 页 / 共 {Math.ceil(total / 10)} 页
            </span>
            <button
              className="rounded border px-3 py-1 hover:border-primary hover:text-primary disabled:cursor-not-allowed disabled:text-muted-foreground"
              disabled={page >= Math.ceil(total / 10)}
              onClick={() => setPage(page + 1)}
            >
              下一页
            </button>
          </div>
        )}
      </div>
    </div>
  );
}
