import { useState, useEffect, useCallback } from 'react';
import {
  Drawer, Form, Select, Checkbox, Slider, DatePicker, Switch,
  Button, Statistic, Row, Col, Descriptions, Alert, Spin, App, Grid, Space,
} from 'antd';
import { ExportOutlined, EyeOutlined } from '@ant-design/icons';
import { api } from '@/lib/api';
import type {
  Cut, Campaign, ExportContactsPreviewResult, ExportContactsResult,
} from '@/types/api';

const OUTCOME_OPTIONS = [
  { label: 'Spoke With', value: 'SPOKE_WITH' },
  { label: 'Left Literature', value: 'LEFT_LITERATURE' },
  { label: 'Come Back Later', value: 'COME_BACK_LATER' },
  { label: 'Not Home', value: 'NOT_HOME' },
  { label: 'Refused', value: 'REFUSED' },
  { label: 'Moved', value: 'MOVED' },
  { label: 'Already Voted', value: 'ALREADY_VOTED' },
];

const SUPPORT_LEVEL_MARKS: Record<number, string> = {
  1: 'Strong',
  2: 'Likely',
  3: 'Unsure',
  4: 'Oppose',
};

interface Props {
  open: boolean;
  onClose: () => void;
  cuts: Cut[];
  /** If provided, pre-fills the campaign selector */
  preselectedCampaignId?: string;
  /** If provided, pre-fills the cut selector */
  preselectedCutIds?: string[];
}

export default function ExportContactsModal({
  open, onClose, cuts, preselectedCampaignId, preselectedCutIds,
}: Props) {
  const { message } = App.useApp();
  const [form] = Form.useForm();
  const [campaigns, setCampaigns] = useState<Campaign[]>([]);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const [preview, setPreview] = useState<ExportContactsPreviewResult | null>(null);
  const [previewing, setPreviewing] = useState(false);
  const [exporting, setExporting] = useState(false);
  const [loadingCampaigns, setLoadingCampaigns] = useState(false);

  // Load campaigns on mount
  useEffect(() => {
    if (!open) return;
    setLoadingCampaigns(true);
    api.get('/campaigns', { params: { limit: 100, status: 'ACTIVE' } })
      .then(({ data }) => setCampaigns(data.campaigns || []))
      .catch(() => {})
      .finally(() => setLoadingCampaigns(false));
  }, [open]);

  // Set defaults when modal opens
  useEffect(() => {
    if (open) {
      form.setFieldsValue({
        cutIds: preselectedCutIds || [],
        outcomes: ['SPOKE_WITH', 'LEFT_LITERATURE'],
        supportRange: [1, 2],
        hasEmail: true,
        hasSign: false,
        campaignId: preselectedCampaignId || undefined,
      });
      setPreview(null);
    }
  }, [open, form, preselectedCampaignId, preselectedCutIds]);

  const handlePreview = useCallback(async () => {
    try {
      const values = await form.validateFields(['cutIds']);
      const allValues = form.getFieldsValue(true);

      setPreviewing(true);
      setPreview(null);

      const body: Record<string, unknown> = {
        cutIds: values.cutIds,
      };
      if (allValues.outcomes?.length) body.outcomes = allValues.outcomes;
      if (allValues.supportRange) {
        body.supportLevelMin = allValues.supportRange[0];
        body.supportLevelMax = allValues.supportRange[1];
      }
      if (allValues.hasEmail) body.hasEmail = true;
      if (allValues.hasSign) body.hasSign = true;
      if (allValues.visitedSince) {
        body.visitedSince = allValues.visitedSince.toISOString();
      }

      const res = await api.post<ExportContactsPreviewResult>(
        '/map/canvass/export-contacts/preview',
        body,
      );
      setPreview(res.data);
    } catch {
      message.error('Failed to generate preview');
    } finally {
      setPreviewing(false);
    }
  }, [form, message]);

  const handleExport = async () => {
    try {
      const allValues = await form.validateFields();

      if (!allValues.campaignId) {
        message.warning('Please select a target campaign');
        return;
      }

      setExporting(true);

      const body: Record<string, unknown> = {
        cutIds: allValues.cutIds,
        campaignId: allValues.campaignId,
      };
      if (allValues.outcomes?.length) body.outcomes = allValues.outcomes;
      if (allValues.supportRange) {
        body.supportLevelMin = allValues.supportRange[0];
        body.supportLevelMax = allValues.supportRange[1];
      }
      if (allValues.hasEmail) body.hasEmail = true;
      if (allValues.hasSign) body.hasSign = true;
      if (allValues.visitedSince) {
        body.visitedSince = allValues.visitedSince.toISOString();
      }

      const res = await api.post<ExportContactsResult>(
        '/map/canvass/export-contacts',
        body,
      );

      message.success(
        `Exported ${res.data.created} contacts to "${res.data.campaignTitle}"` +
        (res.data.skippedDuplicate ? ` (${res.data.skippedDuplicate} duplicates skipped)` : ''),
      );
      onClose();
    } catch {
      message.error('Export failed');
    } finally {
      setExporting(false);
    }
  };

  return (
    <Drawer
      title="Export Canvass Contacts to Campaign"
      open={open}
      onClose={onClose}
      width={isMobile ? '95vw' : 640}
      placement="right"
      mask={false}
      rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
      extra={
        <Space>
          <Button
            icon={<EyeOutlined />}
            onClick={handlePreview}
            loading={previewing}
          >
            Preview
          </Button>
          <Button
            type="primary"
            icon={<ExportOutlined />}
            onClick={handleExport}
            loading={exporting}
            disabled={!preview || preview.contactsWithEmail === 0}
          >
            Export
          </Button>
        </Space>
      }
    >
      <Form form={form} layout="vertical" size="small">
        <Form.Item
          name="cutIds"
          label="Cuts"
          rules={[{ required: true, message: 'Select at least one cut' }]}
        >
          <Select
            mode="multiple"
            placeholder="Select cuts to export from"
            options={cuts.map(c => ({ label: c.name, value: c.id }))}
            maxTagCount={3}
          />
        </Form.Item>

        <Row gutter={16}>
          <Col xs={24} sm={12}>
            <Form.Item name="outcomes" label="Visit Outcomes">
              <Checkbox.Group options={OUTCOME_OPTIONS} />
            </Form.Item>
          </Col>
          <Col xs={24} sm={12}>
            <Form.Item name="supportRange" label="Support Level Range">
              <Slider
                range
                min={1}
                max={4}
                marks={SUPPORT_LEVEL_MARKS}
                tooltip={{ formatter: (v) => SUPPORT_LEVEL_MARKS[v ?? 1] }}
              />
            </Form.Item>
          </Col>
        </Row>

        <Row gutter={16}>
          <Col xs={12} sm={8}>
            <Form.Item name="hasEmail" label="Has Email" valuePropName="checked">
              <Switch />
            </Form.Item>
          </Col>
          <Col xs={12} sm={8}>
            <Form.Item name="hasSign" label="Has Sign" valuePropName="checked">
              <Switch />
            </Form.Item>
          </Col>
          <Col xs={24} sm={8}>
            <Form.Item name="visitedSince" label="Visited Since">
              <DatePicker style={{ width: '100%' }} />
            </Form.Item>
          </Col>
        </Row>

        <Form.Item
          name="campaignId"
          label="Target Campaign"
          rules={[{ required: true, message: 'Select a campaign' }]}
        >
          <Select
            placeholder="Select campaign"
            loading={loadingCampaigns}
            showSearch
            optionFilterProp="label"
            options={campaigns.map(c => ({ label: `${c.title} (${c.status})`, value: c.id }))}
          />
        </Form.Item>
      </Form>

      {/* Preview Results */}
      {previewing && (
        <div style={{ textAlign: 'center', padding: 16 }}>
          <Spin />
        </div>
      )}

      {preview && !previewing && (
        <div style={{ marginTop: 8 }}>
          <Row gutter={16}>
            <Col span={8}>
              <Statistic title="Total Contacts" value={preview.totalContacts} />
            </Col>
            <Col span={8}>
              <Statistic
                title="With Email"
                value={preview.contactsWithEmail}
                valueStyle={{ color: preview.contactsWithEmail > 0 ? '#52c41a' : '#ff4d4f' }}
              />
            </Col>
            <Col span={8}>
              <Statistic
                title="No Email"
                value={preview.totalContacts - preview.contactsWithEmail}
                valueStyle={{ color: '#faad14' }}
              />
            </Col>
          </Row>

          {preview.byCut.length > 0 && (
            <Descriptions column={1} size="small" style={{ marginTop: 12 }} title="By Cut">
              {preview.byCut.map(c => (
                <Descriptions.Item key={c.cutId} label={c.cutName}>
                  {c.contacts} contacts ({c.withEmail} with email)
                </Descriptions.Item>
              ))}
            </Descriptions>
          )}

          {preview.contactsWithEmail === 0 && (
            <Alert
              type="warning"
              message="No contacts with email addresses found. Adjust your filters."
              showIcon
              style={{ marginTop: 12 }}
            />
          )}
        </div>
      )}
    </Drawer>
  );
}
