import { useEffect, useState, useCallback, useRef } from 'react';
import {
  Typography,
  Table,
  Tag,
  Space,
  Select,
  DatePicker,
  Button,
  Drawer,
  Switch,
  message,
} from 'antd';
import { ReloadOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import type { AuditLogEntry, Instance } from '@/types/api';

const { RangePicker } = DatePicker;

const AUDIT_ACTIONS = [
  'INSTANCE_CREATE',
  'INSTANCE_UPDATE',
  'INSTANCE_DELETE',
  'INSTANCE_START',
  'INSTANCE_STOP',
  'INSTANCE_RESTART',
  'INSTANCE_UPGRADE',
  'BACKUP_CREATE',
  'BACKUP_DELETE',
  'PANGOLIN_SETUP',
  'PANGOLIN_SYNC',
  'USER_LOGIN',
  'USER_CREATE',
  'USER_UPDATE',
  'USER_DELETE',
  'SETTINGS_UPDATE',
];

const actionColors: Record<string, string> = {
  INSTANCE_CREATE: 'green',
  INSTANCE_START: 'green',
  INSTANCE_UPDATE: 'blue',
  INSTANCE_RESTART: 'blue',
  INSTANCE_STOP: 'orange',
  INSTANCE_DELETE: 'red',
  INSTANCE_UPGRADE: 'cyan',
  BACKUP_CREATE: 'purple',
  BACKUP_DELETE: 'red',
  PANGOLIN_SETUP: 'geekblue',
  PANGOLIN_SYNC: 'geekblue',
  USER_LOGIN: 'default',
  USER_CREATE: 'green',
  USER_UPDATE: 'blue',
  USER_DELETE: 'red',
  SETTINGS_UPDATE: 'volcano',
};

export default function AuditLogPage() {
  const [logs, setLogs] = useState<AuditLogEntry[]>([]);
  const [total, setTotal] = useState(0);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [actionFilter, setActionFilter] = useState<string | undefined>();
  const [instanceFilter, setInstanceFilter] = useState<string | undefined>();
  const [dateRange, setDateRange] = useState<[dayjs.Dayjs, dayjs.Dayjs] | null>(null);
  const [instances, setInstances] = useState<Instance[]>([]);
  const [selectedLog, setSelectedLog] = useState<AuditLogEntry | null>(null);
  const [autoRefresh, setAutoRefresh] = useState(false);
  const intervalRef = useRef<ReturnType<typeof setInterval>>(undefined);

  const fetchLogs = useCallback(async () => {
    try {
      const params: Record<string, string> = {
        page: String(page),
        limit: String(pageSize),
      };
      if (actionFilter) params.action = actionFilter;
      if (instanceFilter) params.instanceId = instanceFilter;
      if (dateRange?.[0]) params.from = dateRange[0].startOf('day').toISOString();
      if (dateRange?.[1]) params.to = dateRange[1].endOf('day').toISOString();

      const { data } = await api.get('/audit', { params });
      setLogs(data.data);
      setTotal(data.total);
    } catch {
      message.error('Failed to load audit logs');
    } finally {
      setLoading(false);
    }
  }, [page, pageSize, actionFilter, instanceFilter, dateRange]);

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

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

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

  // Auto-refresh
  useEffect(() => {
    if (autoRefresh) {
      intervalRef.current = setInterval(fetchLogs, 30_000);
    }
    return () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
    };
  }, [autoRefresh, fetchLogs]);

  const columns = [
    {
      title: 'Timestamp',
      dataIndex: 'createdAt',
      width: 180,
      render: (d: string) => dayjs(d).format('YYYY-MM-DD HH:mm:ss'),
    },
    {
      title: 'Action',
      dataIndex: 'action',
      width: 160,
      render: (action: string) => (
        <Tag color={actionColors[action] || 'default'}>{action}</Tag>
      ),
    },
    {
      title: 'Instance',
      dataIndex: 'instance',
      width: 160,
      render: (inst: AuditLogEntry['instance']) => inst?.name || '-',
    },
    {
      title: 'User',
      dataIndex: 'user',
      width: 200,
      render: (user: AuditLogEntry['user']) => user?.email || '-',
    },
    {
      title: 'IP Address',
      dataIndex: 'ipAddress',
      width: 140,
      render: (ip: string | undefined) => ip || '-',
    },
  ];

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16, flexWrap: 'wrap', gap: 8 }}>
        <Typography.Title level={3} style={{ margin: 0 }}>
          Audit Log
        </Typography.Title>
        <Space>
          <span>Auto-refresh</span>
          <Switch size="small" checked={autoRefresh} onChange={setAutoRefresh} />
          <Button icon={<ReloadOutlined />} onClick={fetchLogs}>
            Refresh
          </Button>
        </Space>
      </div>

      <Space wrap style={{ marginBottom: 16 }}>
        <Select
          placeholder="Filter by action"
          allowClear
          style={{ width: 200 }}
          value={actionFilter}
          onChange={(v) => { setActionFilter(v); setPage(1); }}
          options={AUDIT_ACTIONS.map((a) => ({ label: a, value: a }))}
        />
        <Select
          placeholder="Filter by instance"
          allowClear
          style={{ width: 200 }}
          value={instanceFilter}
          onChange={(v) => { setInstanceFilter(v); setPage(1); }}
          options={instances.map((i) => ({ label: i.name, value: i.id }))}
        />
        <RangePicker
          value={dateRange}
          onChange={(vals) => {
            setDateRange(vals as [dayjs.Dayjs, dayjs.Dayjs] | null);
            setPage(1);
          }}
        />
      </Space>

      <Table
        dataSource={logs}
        rowKey="id"
        columns={columns}
        loading={loading}
        onRow={(record) => ({
          onClick: () => setSelectedLog(record),
          style: { cursor: 'pointer' },
        })}
        pagination={{
          current: page,
          pageSize,
          total,
          showSizeChanger: true,
          pageSizeOptions: ['25', '50', '100'],
          onChange: (p, ps) => { setPage(p); setPageSize(ps); },
          showTotal: (t) => `${t} entries`,
        }}
        size="small"
      />

      <Drawer
        title="Audit Log Details"
        open={!!selectedLog}
        onClose={() => setSelectedLog(null)}
        width={520}
      >
        {selectedLog && (
          <Space direction="vertical" style={{ width: '100%' }} size="middle">
            <div>
              <Typography.Text type="secondary">Action</Typography.Text>
              <div>
                <Tag color={actionColors[selectedLog.action] || 'default'}>
                  {selectedLog.action}
                </Tag>
              </div>
            </div>
            <div>
              <Typography.Text type="secondary">Timestamp</Typography.Text>
              <div>{dayjs(selectedLog.createdAt).format('YYYY-MM-DD HH:mm:ss')}</div>
            </div>
            <div>
              <Typography.Text type="secondary">User</Typography.Text>
              <div>{selectedLog.user?.email || selectedLog.userId || '-'}</div>
            </div>
            <div>
              <Typography.Text type="secondary">Instance</Typography.Text>
              <div>{selectedLog.instance?.name || selectedLog.instanceId || '-'}</div>
            </div>
            <div>
              <Typography.Text type="secondary">IP Address</Typography.Text>
              <div>{selectedLog.ipAddress || '-'}</div>
            </div>
            <div>
              <Typography.Text type="secondary">Details</Typography.Text>
              <pre
                style={{
                  background: '#1a1a2e',
                  padding: 12,
                  borderRadius: 6,
                  overflow: 'auto',
                  maxHeight: 400,
                  fontSize: 12,
                }}
              >
                {JSON.stringify(selectedLog.details, null, 2) || 'null'}
              </pre>
            </div>
          </Space>
        )}
      </Drawer>
    </div>
  );
}
