import { useState, useEffect, useRef } from 'react';
import {
  Drawer, Table, Tag, Button, Space, Typography, Spin, Alert, Input,
  Descriptions, Switch, message, Collapse, Badge, Result,
} from 'antd';
import {
  SearchOutlined,
  CheckCircleOutlined,
  CloudServerOutlined,
  HomeOutlined,
} from '@ant-design/icons';
import { api } from '@/lib/api';
import type { DiscoveredInstance, DiscoveryResult, ImportResult } from '@/types/api';

interface Props {
  open: boolean;
  onClose: () => void;
  onImported: () => void;
}

export default function DiscoverInstancesDrawer({ open, onClose, onImported }: Props) {
  const [loading, setLoading] = useState(false);
  const [importing, setImporting] = useState(false);
  const [result, setResult] = useState<DiscoveryResult | null>(null);
  const [importResult, setImportResult] = useState<ImportResult | null>(null);
  const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
  const [editedInstances, setEditedInstances] = useState<Record<string, Partial<DiscoveredInstance>>>({});
  const [error, setError] = useState<string | null>(null);
  const hasScanned = useRef(false);

  const runDiscovery = async () => {
    setLoading(true);
    setError(null);
    setResult(null);
    setImportResult(null);
    setSelectedKeys([]);
    setEditedInstances({});
    try {
      const { data } = await api.post('/instances/discover');
      setResult(data.data);
      // Auto-select all new instances
      const newKeys = (data.data as DiscoveryResult).instances
        .filter((inst) => !inst.isAlreadyRegistered)
        .map((inst) => inst.basePath);
      setSelectedKeys(newKeys);
    } catch (err) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })
        ?.response?.data?.error?.message || 'Discovery failed';
      setError(msg);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    if (open && !hasScanned.current) {
      runDiscovery();
      hasScanned.current = true;
    }
  }, [open]);

  const getEditedValue = (basePath: string, field: keyof DiscoveredInstance, original: unknown) => {
    return editedInstances[basePath]?.[field] ?? original;
  };

  const setEditedField = (basePath: string, field: string, value: unknown) => {
    setEditedInstances((prev) => ({
      ...prev,
      [basePath]: { ...prev[basePath], [field]: value },
    }));
  };

  const handleImport = async () => {
    if (!result) return;
    setImporting(true);
    setImportResult(null);

    const toImport = result.instances
      .filter((inst) => selectedKeys.includes(inst.basePath) && !inst.isAlreadyRegistered)
      .map((inst) => {
        const edits = editedInstances[inst.basePath] || {};
        return {
          name: (edits.name as string) || inst.name,
          slug: (edits.slug as string) || inst.slug,
          domain: inst.domain,
          basePath: inst.basePath,
          composeProject: inst.composeProject,
          portConfig: inst.portConfig,
          adminEmail: inst.adminEmail,
          enableMedia: edits.enableMedia ?? inst.enableMedia,
          enableChat: edits.enableChat ?? inst.enableChat,
          enableGancio: edits.enableGancio ?? inst.enableGancio,
          enableListmonk: edits.enableListmonk ?? inst.enableListmonk,
          enableMonitoring: edits.enableMonitoring ?? inst.enableMonitoring,
          enableDevTools: edits.enableDevTools ?? inst.enableDevTools,
          enablePayments: edits.enablePayments ?? inst.enablePayments,
          enableMeet: edits.enableMeet ?? inst.enableMeet,
          enableSms: edits.enableSms ?? inst.enableSms,
          enableSocial: edits.enableSocial ?? inst.enableSocial,
          enablePeople: edits.enablePeople ?? inst.enablePeople,
        };
      });

    if (toImport.length === 0) {
      message.warning('No instances selected for import');
      setImporting(false);
      return;
    }

    try {
      const { data } = await api.post('/instances/import', { instances: toImport });
      const ir = data.data as ImportResult;
      setImportResult(ir);
      if (ir.summary.succeeded > 0) {
        message.success(`Imported ${ir.summary.succeeded} instance(s)`);
        hasScanned.current = false; // Reset so next open re-scans
        onImported();
      }
      if (ir.summary.failed > 0) {
        message.warning(`${ir.summary.failed} instance(s) failed to import`);
      }
    } catch (err) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })
        ?.response?.data?.error?.message || 'Import failed';
      message.error(msg);
    } finally {
      setImporting(false);
    }
  };

  const columns = [
    {
      title: 'Name',
      key: 'name',
      render: (_: unknown, record: DiscoveredInstance) => (
        <Space direction="vertical" size={0}>
          <Space size="small">
            {record.isParentInstance && <Tag icon={<HomeOutlined />} color="blue">Parent</Tag>}
            {record.isAlreadyRegistered ? (
              <Typography.Text type="secondary">{record.name}</Typography.Text>
            ) : (
              <Input
                size="small"
                value={getEditedValue(record.basePath, 'name', record.name) as string}
                onChange={(e) => setEditedField(record.basePath, 'name', e.target.value)}
                style={{ width: 180 }}
              />
            )}
          </Space>
          <Typography.Text type="secondary" style={{ fontSize: 11 }}>
            {record.domain}
          </Typography.Text>
        </Space>
      ),
    },
    {
      title: 'Source',
      key: 'source',
      width: 100,
      render: (_: unknown, record: DiscoveredInstance) => (
        <Tag
          icon={record.source === 'parent' ? <HomeOutlined /> : <CloudServerOutlined />}
          color={record.source === 'parent' ? 'blue' : 'default'}
        >
          {record.source === 'parent' ? 'Parent' : 'Docker'}
        </Tag>
      ),
    },
    {
      title: 'Status',
      key: 'status',
      width: 120,
      render: (_: unknown, record: DiscoveredInstance) => (
        <Space direction="vertical" size={0}>
          <Tag color={record.isRunning ? 'green' : 'default'}>
            {record.isRunning ? 'Running' : 'Stopped'}
          </Tag>
          <Typography.Text type="secondary" style={{ fontSize: 11 }}>
            {record.runningContainers}/{record.totalContainers} containers
          </Typography.Text>
        </Space>
      ),
    },
    {
      title: 'Tracked',
      key: 'tracked',
      width: 90,
      render: (_: unknown, record: DiscoveredInstance) =>
        record.isAlreadyRegistered ? (
          <Tag color="orange">Already tracked</Tag>
        ) : (
          <Tag color="green">New</Tag>
        ),
    },
  ];

  const expandedRowRender = (record: DiscoveredInstance) => {
    const isEditable = !record.isAlreadyRegistered;
    return (
      <div style={{ padding: '8px 0' }}>
        <Descriptions size="small" column={2} bordered>
          <Descriptions.Item label="Slug">
            {isEditable ? (
              <Input
                size="small"
                value={getEditedValue(record.basePath, 'slug', record.slug) as string}
                onChange={(e) => setEditedField(record.basePath, 'slug', e.target.value)}
              />
            ) : (
              <Typography.Text code>{record.slug}</Typography.Text>
            )}
          </Descriptions.Item>
          <Descriptions.Item label="Admin Email">{record.adminEmail}</Descriptions.Item>
          <Descriptions.Item label="Base Path">
            <Typography.Text code style={{ fontSize: 11 }}>{record.basePath}</Typography.Text>
          </Descriptions.Item>
          <Descriptions.Item label="Compose Project">
            <Typography.Text code>{record.composeProject}</Typography.Text>
          </Descriptions.Item>
          <Descriptions.Item label="Ports" span={2}>
            API:{record.portConfig.api} &nbsp; Admin:{record.portConfig.admin} &nbsp;
            Postgres:{record.portConfig.postgres} &nbsp; Nginx:{record.portConfig.nginx}
          </Descriptions.Item>
        </Descriptions>

        {isEditable && (
          <Collapse
            size="small"
            style={{ marginTop: 8 }}
            items={[{
              key: 'features',
              label: 'Feature Flags',
              children: (
                <Space wrap>
                  {(['enableMedia', 'enableChat', 'enableGancio', 'enableListmonk', 'enableMonitoring', 'enableDevTools', 'enablePayments', 'enableMeet', 'enableSms', 'enableSocial', 'enablePeople'] as const).map((flag) => (
                    <Space key={flag} size="small">
                      <Switch
                        size="small"
                        checked={getEditedValue(record.basePath, flag, record[flag]) as boolean}
                        onChange={(checked) => setEditedField(record.basePath, flag, checked)}
                      />
                      <Typography.Text style={{ fontSize: 12 }}>
                        {flag.replace('enable', '')}
                      </Typography.Text>
                    </Space>
                  ))}
                </Space>
              ),
            }]}
          />
        )}
      </div>
    );
  };

  const selectableInstances = result?.instances.filter((inst) => !inst.isAlreadyRegistered) || [];
  const selectedCount = selectedKeys.filter((key) =>
    selectableInstances.some((inst) => inst.basePath === key)
  ).length;

  return (
    <Drawer
      title="Discover CML Instances"
      placement="right"
      width={720}
      open={open}
      onClose={onClose}
      footer={
        importResult ? (
          <Button type="primary" onClick={onClose}>Done</Button>
        ) : (
          <Space>
            <Button onClick={runDiscovery} icon={<SearchOutlined />} loading={loading}>
              Re-scan
            </Button>
            <Button
              type="primary"
              onClick={handleImport}
              loading={importing}
              disabled={selectedCount === 0 || loading}
            >
              Import Selected ({selectedCount})
            </Button>
          </Space>
        )
      }
    >
      {loading && (
        <div style={{ textAlign: 'center', padding: '60px 0' }}>
          <Spin size="large" />
          <Typography.Paragraph type="secondary" style={{ marginTop: 16 }}>
            Scanning Docker projects and parsing .env files...
          </Typography.Paragraph>
        </div>
      )}

      {error && <Alert type="error" message={error} showIcon style={{ marginBottom: 16 }} />}

      {importResult && (
        <div style={{ marginBottom: 16 }}>
          <Result
            status={importResult.summary.failed === 0 ? 'success' : 'warning'}
            title={`${importResult.summary.succeeded} imported, ${importResult.summary.failed} failed`}
          />
          {importResult.results.filter((r) => !r.success).map((r) => (
            <Alert
              key={r.slug}
              type="error"
              message={`${r.slug}: ${r.error}`}
              style={{ marginBottom: 4 }}
              showIcon
            />
          ))}
          {importResult.results.filter((r) => r.success).map((r) => (
            <Alert
              key={r.slug}
              type="success"
              message={`${r.slug} imported successfully`}
              icon={<CheckCircleOutlined />}
              style={{ marginBottom: 4 }}
              showIcon
            />
          ))}
        </div>
      )}

      {!loading && result && !importResult && (
        <>
          <Alert
            type="info"
            showIcon
            message={
              <Space>
                <span>
                  Found <strong>{result.summary.total}</strong> instance(s)
                </span>
                <Badge count={result.summary.newInstances} style={{ backgroundColor: '#52c41a' }} overflowCount={99}>
                  <Tag>New</Tag>
                </Badge>
                <Badge count={result.summary.alreadyRegistered} style={{ backgroundColor: '#faad14' }} overflowCount={99}>
                  <Tag>Already tracked</Tag>
                </Badge>
                {result.summary.parentFound && <Tag icon={<HomeOutlined />} color="blue">Parent found</Tag>}
              </Space>
            }
            style={{ marginBottom: 16 }}
          />

          {result.instances.length === 0 ? (
            <Result
              icon={<CloudServerOutlined style={{ color: '#999' }} />}
              title="No CML instances found"
              subTitle="No running Docker Compose projects with the CML fingerprint were detected."
            />
          ) : (
            <Table
              dataSource={result.instances}
              columns={columns}
              rowKey="basePath"
              size="small"
              pagination={false}
              expandable={{ expandedRowRender }}
              rowSelection={{
                selectedRowKeys: selectedKeys,
                onChange: (keys) => setSelectedKeys(keys as string[]),
                getCheckboxProps: (record) => ({
                  disabled: record.isAlreadyRegistered,
                }),
              }}
              rowClassName={(record) => record.isAlreadyRegistered ? 'ant-table-row-disabled' : ''}
            />
          )}
        </>
      )}
    </Drawer>
  );
}
