import { useState, useEffect, useCallback } from 'react';
import { Table, Button, Drawer, Form, Input, Select, InputNumber, Space, Tag, Progress, App, Typography, Popconfirm, Divider, Alert } from 'antd';
import { PlusOutlined, PlayCircleOutlined, PauseCircleOutlined, CaretRightOutlined, DeleteOutlined, EyeOutlined, SendOutlined, PhoneOutlined } from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import { api } from '@/lib/api';
import type { SmsCampaign, SmsContactList, SmsPaginatedResponse } from '@/types/sms';
import type { AppOutletContext } from '@/types/api';
import { useMobile } from '@/hooks/useMobile';
import { useOutletContext } from 'react-router-dom';

const { TextArea } = Input;
const { Text } = Typography;

const STATUS_COLORS: Record<string, string> = {
  DRAFT: 'default',
  RUNNING: 'processing',
  PAUSED: 'warning',
  COMPLETED: 'success',
  FAILED: 'error',
};

export default function SmsCampaignsPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { message } = App.useApp();
  const { isMobile } = useMobile();

  const [campaigns, setCampaigns] = useState<SmsCampaign[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [loading, setLoading] = useState(true);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [contactLists, setContactLists] = useState<SmsContactList[]>([]);
  const [createForm] = Form.useForm();
  const [saving, setSaving] = useState(false);

  // Preview & Test
  const [testPreview, setTestPreview] = useState('');
  const [testPhone, setTestPhone] = useState('');
  const [testSending, setTestSending] = useState(false);

  useEffect(() => {
    setPageHeader({ title: 'SMS Campaigns', subtitle: 'Create and manage SMS campaigns' });
  }, [setPageHeader]);

  const fetchCampaigns = useCallback(async () => {
    setLoading(true);
    try {
      const { data } = await api.get<SmsPaginatedResponse<SmsCampaign>>('/sms/campaigns', { params: { page, limit: 50 } });
      setCampaigns(data.items);
      setTotal(data.total);
    } finally {
      setLoading(false);
    }
  }, [page]);

  const fetchContactLists = useCallback(async () => {
    try {
      const { data } = await api.get<SmsPaginatedResponse<SmsContactList>>('/sms/contacts', { params: { limit: 100 } });
      setContactLists(data.items);
    } catch { /* ignore */ }
  }, []);

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

  // Auto-refresh active campaigns
  useEffect(() => {
    const hasActive = campaigns.some((c) => c.status === 'RUNNING');
    if (!hasActive) return;
    const interval = setInterval(fetchCampaigns, 5000);
    return () => clearInterval(interval);
  }, [campaigns, fetchCampaigns]);

  const closeDrawer = () => { setDrawerOpen(false); setTestPreview(''); };

  const handleCreate = async (values: { name: string; messageTemplate: string; contactListId: string; delayBetweenMs: number }) => {
    setSaving(true);
    try {
      await api.post('/sms/campaigns', values);
      message.success('Campaign created');
      closeDrawer();
      createForm.resetFields();
      fetchCampaigns();
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Create failed';
      message.error(msg);
    } finally {
      setSaving(false);
    }
  };

  const handleStart = async (id: string) => {
    try {
      const { data } = await api.post(`/sms/campaigns/${id}/start`);
      message.success(`Campaign started — ${data.enqueued} messages queued`);
      fetchCampaigns();
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : 'Start failed';
      message.error(msg);
    }
  };

  const handlePause = async (id: string) => {
    try {
      await api.post(`/sms/campaigns/${id}/pause`);
      message.success('Campaign paused');
      fetchCampaigns();
    } catch { message.error('Pause failed'); }
  };

  const handleResume = async (id: string) => {
    try {
      const { data } = await api.post(`/sms/campaigns/${id}/resume`);
      message.success(`Campaign resumed — ${data.enqueued} messages re-queued`);
      fetchCampaigns();
    } catch { message.error('Resume failed'); }
  };

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/sms/campaigns/${id}`);
      message.success('Campaign deleted');
      fetchCampaigns();
    } catch { message.error('Delete failed — only DRAFT campaigns can be deleted'); }
  };

  const handlePreviewTest = () => {
    const template = createForm.getFieldValue('messageTemplate') || '';
    // Substitute placeholders with sample values
    const preview = template
      .replace(/\{name\}/g, 'Jane Doe')
      .replace(/\{phone\}/g, '+1 555 000 0000');
    setTestPreview(preview);
  };

  const handleSendTestCampaign = async () => {
    if (!testPhone.trim() || !testPreview.trim()) {
      message.warning('Enter a test phone number and ensure the message preview is visible');
      return;
    }
    setTestSending(true);
    try {
      await api.post('/sms/messages/send', { phone: testPhone.trim(), message: testPreview });
      message.success('Test message sent');
    } catch {
      message.error('Failed to send test message');
    } finally {
      setTestSending(false);
    }
  };

  const columns: ColumnsType<SmsCampaign> = [
    { title: 'Name', dataIndex: 'name', ellipsis: true },
    {
      title: 'Status',
      dataIndex: 'status',
      width: 110,
      render: (status) => <Tag color={STATUS_COLORS[status] || 'default'}>{status}</Tag>,
    },
    {
      title: 'Progress',
      width: 200,
      render: (_, record) => {
        const pct = record.totalRecipients > 0 ? Math.round(((record.totalSent + record.totalFailed) / record.totalRecipients) * 100) : 0;
        return (
          <Space direction="vertical" size={0} style={{ width: '100%' }}>
            <Progress percent={pct} size="small" status={record.totalFailed > 0 ? 'exception' : undefined} />
            <Text type="secondary" style={{ fontSize: 12 }}>
              {record.totalSent} sent / {record.totalFailed} failed / {record.totalRecipients} total
            </Text>
          </Space>
        );
      },
    },
    {
      title: 'Responses',
      dataIndex: 'totalResponded',
      width: 100,
      responsive: ['lg'] as any,
      render: (v, record) => {
        const rate = record.totalSent > 0 ? ((v / record.totalSent) * 100).toFixed(1) : '0';
        return <Text>{v} ({rate}%)</Text>;
      },
    },
    {
      title: 'Contact List',
      width: 150,
      responsive: ['md'] as any,
      render: (_, record) => record.contactList?.name || <Text type="secondary">-</Text>,
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      width: 100,
      responsive: ['md'] as any,
      render: (d) => new Date(d).toLocaleDateString(),
    },
    {
      title: 'Actions',
      width: 160,
      render: (_, record) => (
        <Space>
          {record.status === 'DRAFT' && (
            <Popconfirm title="Start this campaign?" onConfirm={() => handleStart(record.id)}>
              <Button size="small" type="primary" icon={<PlayCircleOutlined />}>{!isMobile && 'Start'}</Button>
            </Popconfirm>
          )}
          {record.status === 'RUNNING' && (
            <Button size="small" icon={<PauseCircleOutlined />} onClick={() => handlePause(record.id)}>{!isMobile && 'Pause'}</Button>
          )}
          {record.status === 'PAUSED' && (
            <Button size="small" icon={<CaretRightOutlined />} onClick={() => handleResume(record.id)}>{!isMobile && 'Resume'}</Button>
          )}
          {record.status === 'DRAFT' && (
            <Popconfirm title="Delete campaign?" onConfirm={() => handleDelete(record.id)}>
              <Button size="small" danger icon={<DeleteOutlined />} />
            </Popconfirm>
          )}
        </Space>
      ),
    },
  ];

  const drawerWidth = isMobile ? '100%' : 480;

  return (
    <>
      <div style={{ marginRight: drawerOpen && !isMobile ? 480 : 0, transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)' }}>
        <Space style={{ marginBottom: 16 }}>
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => { setDrawerOpen(true); fetchContactLists(); }}
          >
            New Campaign
          </Button>
        </Space>

        <Table
          rowKey="id"
          columns={columns}
          dataSource={campaigns}
          loading={loading}
          pagination={{ current: page, total, pageSize: 50, onChange: setPage }}
          size="middle"
          scroll={{ x: 'max-content' }}
        />
      </div>

      <Drawer
        title="New SMS Campaign"
        open={drawerOpen}
        onClose={closeDrawer}
        destroyOnHidden
        mask={false}
        width={drawerWidth}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        extra={
          <Space>
            <Button onClick={closeDrawer}>Cancel</Button>
            <Button type="primary" loading={saving} onClick={() => createForm.submit()}>
              Create
            </Button>
          </Space>
        }
      >
        <Form form={createForm} layout="vertical" onFinish={handleCreate} initialValues={{ delayBetweenMs: 3000 }}>
          <Form.Item name="name" label="Campaign Name" rules={[{ required: true }]}>
            <Input placeholder="e.g. Ward 6 Outreach" />
          </Form.Item>
          <Form.Item name="contactListId" label="Contact List" rules={[{ required: true }]}>
            <Select
              placeholder="Select a contact list"
              options={contactLists.map((l) => ({
                value: l.id,
                label: `${l.name} (${l.totalContacts} contacts)`,
              }))}
            />
          </Form.Item>
          <Form.Item name="messageTemplate" label="Message Template" rules={[{ required: true }]} extra="Use {name}, {phone} for substitution">
            <TextArea rows={4} maxLength={1600} showCount placeholder="Hi {name}, ..." />
          </Form.Item>

          <Divider dashed style={{ margin: '12px 0' }} />
          <Button icon={<EyeOutlined />} onClick={handlePreviewTest} style={{ marginBottom: 12 }}>
            Preview & Test
          </Button>

          {testPreview && (
            <Alert
              type="info"
              message="Message Preview"
              description={
                <div>
                  <div style={{
                    background: 'rgba(0,0,0,0.05)',
                    padding: 12,
                    borderRadius: 6,
                    marginBottom: 12,
                    whiteSpace: 'pre-wrap',
                    fontFamily: 'monospace',
                    fontSize: 13,
                  }}>
                    {testPreview}
                  </div>
                  <Space>
                    <Input
                      value={testPhone}
                      onChange={(e) => setTestPhone(e.target.value)}
                      placeholder="+1 555 123 4567"
                      prefix={<PhoneOutlined />}
                      style={{ width: 200 }}
                    />
                    <Button
                      type="primary"
                      size="small"
                      icon={<SendOutlined />}
                      loading={testSending}
                      onClick={handleSendTestCampaign}
                      disabled={!testPhone.trim()}
                    >
                      Send Test
                    </Button>
                  </Space>
                </div>
              }
              style={{ marginBottom: 16 }}
            />
          )}

          <Form.Item name="delayBetweenMs" label="Delay Between Messages (ms)">
            <InputNumber min={1000} max={60000} step={500} style={{ width: '100%' }} />
          </Form.Item>
        </Form>
      </Drawer>
    </>
  );
}
