import { useState, useEffect, useCallback, useRef } from 'react';
import {
  Card,
  Button,
  Space,
  Badge,
  Descriptions,
  Table,
  Collapse,
  Popconfirm,
  App,
  Row,
  Col,
  Spin,
  Radio,
  Alert,
} from 'antd';
import {
  SyncOutlined,
  LinkOutlined,
  ApiOutlined,
  ReloadOutlined,
  DesktopOutlined,
  SettingOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { useOutletContext } from 'react-router-dom';
import { api } from '@/lib/api';
import { buildServiceUrl } from '@/lib/service-url';
import type { AppOutletContext } from '@/components/AppLayout';
import type {
  ListmonkStatus,
  ListmonkStats,
  ListmonkSyncResult,
  ListmonkSyncAllResult,
  ServicesConfig,
} from '@/types/api';

dayjs.extend(relativeTime);

export default function ListmonkPage() {
  const { message } = App.useApp();
  const [status, setStatus] = useState<ListmonkStatus | null>(null);
  const [stats, setStats] = useState<ListmonkStats | null>(null);
  const [config, setConfig] = useState<ServicesConfig | null>(null);
  const [eventSyncStats, setEventSyncStats] = useState<{ enabled: boolean; lastSyncAt: string | null; todaySyncCount: number } | null>(null);
  const [loading, setLoading] = useState(true);
  const [syncing, setSyncing] = useState<Record<string, boolean>>({});
  const [iframeSrc, setIframeSrc] = useState<string | null>(null);
  const [iframeLoading, setIframeLoading] = useState(false);
  const [iframeError, setIframeError] = useState<string | null>(null);
  const iframeInitialized = useRef(false);
  const [activeTab, setActiveTab] = useState<'management' | 'admin'>('management');

  const fetchStatus = useCallback(async () => {
    try {
      const res = await api.get<ListmonkStatus>('/listmonk');
      setStatus(res.data);
    } catch {
      // Status fetch failed — leave null
    }
  }, []);

  const fetchStats = useCallback(async () => {
    try {
      const res = await api.get<ListmonkStats>('/listmonk/stats');
      setStats(res.data);
    } catch {
      // Stats fetch may fail if not initialized
    }
  }, []);

  const fetchConfig = useCallback(async () => {
    try {
      const res = await api.get<ServicesConfig>('/services/config');
      setConfig(res.data);
    } catch {
      // Config fetch failed — leave null
    }
  }, []);

  const fetchEventSyncStats = useCallback(async () => {
    try {
      const res = await api.get<{ enabled: boolean; lastSyncAt: string | null; todaySyncCount: number }>('/listmonk/event-sync-stats');
      setEventSyncStats(res.data);
    } catch {
      // Event sync stats fetch failed — leave null
    }
  }, []);

  const fetchAll = useCallback(async () => {
    setLoading(true);
    await Promise.all([fetchStatus(), fetchStats(), fetchConfig(), fetchEventSyncStats()]);
    setLoading(false);
  }, [fetchStatus, fetchStats, fetchConfig, fetchEventSyncStats]);

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

  const handleTestConnection = useCallback(async () => {
    setSyncing(s => ({ ...s, test: true }));
    try {
      const res = await api.post<{ success: boolean; message: string }>('/listmonk/test-connection');
      if (res.data.success) {
        message.success(res.data.message);
      } else {
        message.warning(res.data.message);
      }
      await fetchStatus();
    } catch {
      message.error('Failed to test connection');
    } finally {
      setSyncing(s => ({ ...s, test: false }));
    }
  }, [fetchStatus]);

  const handleSync = async (type: 'participants' | 'locations' | 'users') => {
    setSyncing(s => ({ ...s, [type]: true }));
    try {
      const res = await api.post<ListmonkSyncResult>(`/listmonk/sync/${type}`);
      if (res.data.success) {
        message.success(res.data.message);
        if (res.data.results && res.data.results.failed > 0) {
          message.warning(`${res.data.results.failed} failed — check logs for details`);
        }
      } else {
        message.error(res.data.message);
      }
      await Promise.all([fetchStatus(), fetchStats()]);
    } catch {
      message.error(`Failed to sync ${type}`);
    } finally {
      setSyncing(s => ({ ...s, [type]: false }));
    }
  };

  const handleSyncAll = async () => {
    setSyncing(s => ({ ...s, all: true }));
    try {
      const res = await api.post<ListmonkSyncAllResult>('/listmonk/sync/all');
      if (res.data.success) {
        message.success(res.data.message);
        if (res.data.results) {
          const { participants, locations, users } = res.data.results;
          const totalFailed = participants.failed + locations.failed + users.failed;
          if (totalFailed > 0) {
            message.warning(`${totalFailed} total failures — check logs for details`);
          }
        }
      } else {
        message.error(res.data.message);
      }
      await Promise.all([fetchStatus(), fetchStats()]);
    } catch {
      message.error('Failed to sync all');
    } finally {
      setSyncing(s => ({ ...s, all: false }));
    }
  };

  const handleReinitialize = async () => {
    setSyncing(s => ({ ...s, reinit: true }));
    try {
      await api.post('/listmonk/reinitialize');
      message.success('Lists reinitialized');
      await Promise.all([fetchStatus(), fetchStats()]);
    } catch {
      message.error('Failed to reinitialize lists');
    } finally {
      setSyncing(s => ({ ...s, reinit: false }));
    }
  };

  const { setPageHeader } = useOutletContext<AppOutletContext>();

  const buildProxyAuthUrl = useCallback((token: string) => {
    if (!config) return null;
    const base = buildServiceUrl(config.listmonkSubdomain, config.domain, config.listmonkPort);
    return `${base}/auth?token=${encodeURIComponent(token)}`;
  }, [config]);

  const loadIframe = useCallback(async () => {
    if (iframeInitialized.current && iframeSrc) return;
    setIframeLoading(true);
    setIframeError(null);
    try {
      const res = await api.get<{ port: number; token: string }>('/listmonk/proxy-url');
      const url = buildProxyAuthUrl(res.data.token);
      if (!url) throw new Error('Config not loaded');
      setIframeSrc(url);
      iframeInitialized.current = true;
    } catch {
      setIframeError('Failed to load Listmonk admin — ensure the proxy is running');
    } finally {
      setIframeLoading(false);
    }
  }, [iframeSrc, buildProxyAuthUrl]);

  const handleOpenListmonk = useCallback(async () => {
    try {
      const res = await api.get<{ port: number; token: string }>('/listmonk/proxy-url');
      const url = buildProxyAuthUrl(res.data.token);
      if (url) window.open(url, '_blank', 'noopener,noreferrer');
    } catch {
      message.error('Failed to get Listmonk auth URL');
    }
  }, [buildProxyAuthUrl]);

  useEffect(() => {
    setPageHeader({ title: 'Newsletter / Listmonk', fullBleed: activeTab === 'admin' });
    return () => setPageHeader(null);
  }, [setPageHeader, activeTab]);

  if (loading) {
    return (
      <div style={{ textAlign: 'center', padding: 80 }}>
        <Spin size="large" />
      </div>
    );
  }

  return (
    <div>
      <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap', marginBottom: 16 }}>
        <Radio.Group
          value={activeTab}
          onChange={(e) => {
            const tab = e.target.value as 'management' | 'admin';
            setActiveTab(tab);
            if (tab === 'admin') loadIframe();
          }}
          optionType="button"
          buttonStyle="solid"
          size="small"
        >
          <Radio.Button value="management"><SettingOutlined /> Management</Radio.Button>
          <Radio.Button value="admin"><DesktopOutlined /> Listmonk Admin</Radio.Button>
        </Radio.Group>
        <Button
          size="small"
          icon={<ApiOutlined />}
          loading={syncing.test}
          onClick={handleTestConnection}
        >
          Test Connection
        </Button>
        {config && (
          <Button
            size="small"
            icon={<LinkOutlined />}
            onClick={handleOpenListmonk}
          >
            Open Listmonk
          </Button>
        )}
      </div>
      {activeTab === 'management' && (
        <>
          <Row gutter={[16, 16]}>
            <Col xs={24} lg={12}>
              <Card title="Status" size="small">
                <Descriptions column={1} size="small">
                  <Descriptions.Item label="Sync Enabled">
                    <Badge
                      status={status?.enabled ? 'success' : 'error'}
                      text={status?.enabled ? 'Enabled' : 'Disabled'}
                    />
                  </Descriptions.Item>
                  <Descriptions.Item label="Connection">
                    <Badge
                      status={status?.connected ? 'success' : status?.enabled ? 'warning' : 'default'}
                      text={status?.connected ? 'Connected' : status?.enabled ? 'Disconnected' : 'N/A'}
                    />
                  </Descriptions.Item>
                  <Descriptions.Item label="Lists Initialized">
                    <Badge
                      status={status?.initialized ? 'success' : 'default'}
                      text={status?.initialized ? 'Yes' : 'No'}
                    />
                  </Descriptions.Item>
                  <Descriptions.Item label="Last Sync">
                    {status?.lastSyncAt ? dayjs(status.lastSyncAt).fromNow() : 'Never'}
                  </Descriptions.Item>
                  <Descriptions.Item label="Last Error">
                    {status?.lastError || 'None'}
                  </Descriptions.Item>
                </Descriptions>
              </Card>
            </Col>

            <Col xs={24} lg={12}>
              <Card title="Sync Actions" size="small">
                <Space direction="vertical" style={{ width: '100%' }} size="middle">
                  <Row gutter={[8, 8]}>
                    <Col xs={24} sm={12}>
                      <Button
                        block
                        icon={<SyncOutlined />}
                        loading={syncing.participants}
                        onClick={() => handleSync('participants')}
                        disabled={!status?.enabled}
                      >
                        Sync Participants
                      </Button>
                    </Col>
                    <Col xs={24} sm={12}>
                      <Button
                        block
                        icon={<SyncOutlined />}
                        loading={syncing.locations}
                        onClick={() => handleSync('locations')}
                        disabled={!status?.enabled}
                      >
                        Sync Locations
                      </Button>
                    </Col>
                    <Col xs={24} sm={12}>
                      <Button
                        block
                        icon={<SyncOutlined />}
                        loading={syncing.users}
                        onClick={() => handleSync('users')}
                        disabled={!status?.enabled}
                      >
                        Sync Users
                      </Button>
                    </Col>
                    <Col xs={24} sm={12}>
                      <Popconfirm
                        title="Sync all contacts to Listmonk?"
                        onConfirm={handleSyncAll}
                        disabled={!status?.enabled}
                      >
                        <Button
                          block
                          type="primary"
                          icon={<SyncOutlined />}
                          loading={syncing.all}
                          disabled={!status?.enabled}
                        >
                          Sync All
                        </Button>
                      </Popconfirm>
                    </Col>
                  </Row>
                </Space>
              </Card>
            </Col>
          </Row>

          <Card title="List Statistics" size="small" style={{ marginTop: 16 }}>
            <Table
              dataSource={stats?.lists || []}
              rowKey="name"
              size="small"
              loading={loading}
              pagination={false}
              scroll={{ x: 'max-content' }}
              columns={[
                { title: 'List Name', dataIndex: 'name', key: 'name' },
                {
                  title: 'Subscribers',
                  dataIndex: 'subscriberCount',
                  key: 'subscriberCount',
                  width: 120,
                  align: 'right' as const,
                },
              ]}
              locale={{ emptyText: status?.initialized ? 'No lists found' : 'Lists not initialized — run a sync or reinitialize' }}
            />
          </Card>

          <Card title="Event-Driven Sync" size="small" style={{ marginTop: 16 }}>
            <Descriptions column={1} size="small">
              <Descriptions.Item label="Status">
                <Badge
                  status={eventSyncStats?.enabled ? 'success' : 'default'}
                  text={eventSyncStats?.enabled ? 'Active' : 'Disabled'}
                />
              </Descriptions.Item>
              <Descriptions.Item label="Last Event Sync">
                {eventSyncStats?.lastSyncAt ? dayjs(eventSyncStats.lastSyncAt).fromNow() : 'No events yet'}
              </Descriptions.Item>
              <Descriptions.Item label="Today&apos;s Syncs">
                {eventSyncStats?.todaySyncCount ?? 0}
              </Descriptions.Item>
            </Descriptions>
            <Alert
              type="info"
              message="Shift signups, canvass completions, and campaign emails are automatically synced to Listmonk when LISTMONK_SYNC_ENABLED=true."
              showIcon
              style={{ marginTop: 12 }}
            />
          </Card>

          <Collapse
            style={{ marginTop: 16 }}
            items={[
              {
                key: 'advanced',
                label: 'Advanced',
                children: (
                  <Space>
                    <Popconfirm
                      title="Reinitialize Lists"
                      description="This will re-create any missing lists in Listmonk. Existing lists are preserved."
                      onConfirm={handleReinitialize}
                      okText="Reinitialize"
                    >
                      <Button icon={<ReloadOutlined />} loading={syncing.reinit} disabled={!status?.enabled}>
                        Reinitialize Lists
                      </Button>
                    </Popconfirm>
                  </Space>
                ),
              },
            ]}
          />
        </>
      )}

      {activeTab === 'admin' && (
        <div>
          {iframeLoading && (
            <div style={{ textAlign: 'center', padding: 80 }}>
              <Spin size="large" />
            </div>
          )}
          {iframeError && (
            <Alert
              type="error"
              message={iframeError}
              showIcon
              action={
                <Button size="small" onClick={loadIframe}>
                  Retry
                </Button>
              }
              style={{ marginBottom: 16 }}
            />
          )}
          {iframeSrc && !iframeLoading && (
            <iframe
              src={iframeSrc}
              style={{
                width: '100%',
                height: 'calc(100vh - 64px)',
                border: 'none',
                display: 'block',
              }}
              title="Listmonk Admin"
            />
          )}
        </div>
      )}
    </div>
  );
}
