import { useEffect, useState, useCallback } from 'react';
import {
  Typography,
  Table,
  Tag,
  Space,
  Select,
  Button,
  Popconfirm,
  Statistic,
  Card,
  Row,
  Col,
  message,
} from 'antd';
import {
  ReloadOutlined,
  CloudDownloadOutlined,
  DeleteOutlined,
  CloudUploadOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import type { Instance } from '@/types/api';

interface BackupRow {
  id: string;
  instanceId: string;
  status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED';
  archivePath?: string;
  sizeBytes?: string | number | null;
  manifest?: Record<string, unknown>;
  startedAt: string;
  completedAt?: string;
  errorMessage?: string;
  s3Uploaded: boolean;
  instance?: { id: string; name: string; slug: string } | null;
}

function formatSize(bytes: string | number | null | undefined): string {
  if (bytes == null) return '-';
  const n = typeof bytes === 'string' ? parseInt(bytes, 10) : bytes;
  if (n < 1024) return `${n} B`;
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
  if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
  return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
}

export default function BackupsPage() {
  const [backups, setBackups] = useState<BackupRow[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [instanceFilter, setInstanceFilter] = useState<string | undefined>();
  const [instances, setInstances] = useState<Instance[]>([]);
  const [backingUpAll, setBackingUpAll] = useState(false);

  const fetchBackups = useCallback(async () => {
    try {
      const params: Record<string, string> = { page: String(page), limit: String(pageSize) };
      if (instanceFilter) params.instanceId = instanceFilter;
      const { data } = await api.get('/backups', { params });
      setBackups(data.data);
      setTotal(data.total);
    } catch {
      message.error('Failed to load backups');
    } finally {
      setLoading(false);
    }
  }, [page, pageSize, instanceFilter]);

  const fetchInstances = useCallback(async () => {
    try {
      const { data } = await api.get('/instances');
      setInstances(data.data);
    } catch {
      // Silently fail
    }
  }, []);

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

  useEffect(() => {
    setLoading(true);
    fetchBackups();
  }, [fetchBackups]);

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/backups/${id}`);
      message.success('Backup deleted');
      fetchBackups();
    } catch {
      message.error('Failed to delete backup');
    }
  };

  const handleDownload = (id: string) => {
    window.open(`/api/backups/${id}/download`, '_blank');
  };

  const handleBackupAll = async () => {
    const running = instances.filter((i) => i.status === 'RUNNING');
    if (running.length === 0) {
      message.warning('No running instances to backup');
      return;
    }
    setBackingUpAll(true);
    try {
      await Promise.all(running.map((inst) => api.post(`/instances/${inst.id}/backup`)));
      message.success(`Backup started for ${running.length} instance(s)`);
      fetchBackups();
    } catch {
      message.error('Some backups failed to start');
    } finally {
      setBackingUpAll(false);
    }
  };

  // Summary stats
  const totalSize = backups
    .filter((b) => b.status === 'COMPLETED' && b.sizeBytes)
    .reduce((sum, b) => sum + (typeof b.sizeBytes === 'string' ? parseInt(b.sizeBytes, 10) : (b.sizeBytes || 0)), 0);
  const lastBackup = backups.find((b) => b.status === 'COMPLETED');

  const statusColors: Record<string, string> = {
    COMPLETED: 'green',
    FAILED: 'red',
    IN_PROGRESS: 'processing',
    PENDING: 'default',
  };

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16, flexWrap: 'wrap', gap: 8 }}>
        <Typography.Title level={3} style={{ margin: 0 }}>
          Backups
        </Typography.Title>
        <Space>
          <Button
            icon={<CloudUploadOutlined />}
            onClick={handleBackupAll}
            loading={backingUpAll}
          >
            Backup All Running
          </Button>
          <Button icon={<ReloadOutlined />} onClick={fetchBackups}>
            Refresh
          </Button>
        </Space>
      </div>

      <Row gutter={[16, 16]} style={{ marginBottom: 16 }}>
        <Col xs={12} sm={8}>
          <Card size="small">
            <Statistic title="Total Backups" value={total} />
          </Card>
        </Col>
        <Col xs={12} sm={8}>
          <Card size="small">
            <Statistic title="Total Size" value={formatSize(totalSize)} />
          </Card>
        </Col>
        <Col xs={24} sm={8}>
          <Card size="small">
            <Statistic
              title="Last Backup"
              value={lastBackup ? dayjs(lastBackup.completedAt).format('MMM D, HH:mm') : 'Never'}
            />
          </Card>
        </Col>
      </Row>

      <Space wrap style={{ marginBottom: 16 }}>
        <Select
          placeholder="Filter by instance"
          allowClear
          style={{ width: 220 }}
          value={instanceFilter}
          onChange={(v) => { setInstanceFilter(v); setPage(1); }}
          options={instances.map((i) => ({ label: i.name, value: i.id }))}
        />
      </Space>

      <Table
        dataSource={backups}
        rowKey="id"
        loading={loading}
        size="small"
        pagination={{
          current: page,
          pageSize,
          total,
          showSizeChanger: true,
          pageSizeOptions: ['25', '50', '100'],
          onChange: (p, ps) => { setPage(p); setPageSize(ps); },
          showTotal: (t) => `${t} backups`,
        }}
        columns={[
          {
            title: 'Instance',
            dataIndex: 'instance',
            width: 180,
            render: (inst: BackupRow['instance'], record: BackupRow) => {
              const isRemote = record.manifest?.source === 'remote';
              return (
                <Space size={4}>
                  <span>{inst?.name || '-'}</span>
                  {isRemote && <Tag color="blue">remote</Tag>}
                </Space>
              );
            },
          },
          {
            title: 'Status',
            dataIndex: 'status',
            width: 110,
            render: (s: string) => <Tag color={statusColors[s]}>{s}</Tag>,
          },
          {
            title: 'Started',
            dataIndex: 'startedAt',
            width: 150,
            render: (d: string) => dayjs(d).format('YYYY-MM-DD HH:mm'),
          },
          {
            title: 'Completed',
            dataIndex: 'completedAt',
            width: 150,
            render: (d: string | null) => (d ? dayjs(d).format('YYYY-MM-DD HH:mm') : '-'),
          },
          {
            title: 'Size',
            dataIndex: 'sizeBytes',
            width: 100,
            render: (b: string | number | null) => formatSize(b),
          },
          {
            title: 'Actions',
            width: 100,
            render: (_: unknown, record: BackupRow) => (
              <Space size="small">
                {record.status === 'COMPLETED' && (
                  <Button
                    icon={<CloudDownloadOutlined />}
                    size="small"
                    type="text"
                    onClick={() => handleDownload(record.id)}
                  />
                )}
                <Popconfirm
                  title="Delete this backup?"
                  onConfirm={() => handleDelete(record.id)}
                >
                  <Button icon={<DeleteOutlined />} size="small" type="text" danger />
                </Popconfirm>
              </Space>
            ),
          },
        ]}
      />
    </div>
  );
}
