import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import {
  Table,
  Button,
  Input,
  Select,
  Tag,
  Space,
  Drawer,
  Form,
  Switch,
  Popconfirm,
  message,
  Row,
  Col,
  Divider,
  Tooltip,
  Grid,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  SearchOutlined,
  StarFilled,
  MailOutlined,
  LinkOutlined,
  EyeOutlined,
  QuestionCircleOutlined,
  ExportOutlined,
  QrcodeOutlined,
  DatabaseOutlined,
} from '@ant-design/icons';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import dayjs from 'dayjs';
import { useOutletContext, useNavigate } from 'react-router-dom';
import { api } from '@/lib/api';
import { buildServiceUrl } from '@/lib/service-url';
import { useAuthStore } from '@/stores/auth.store';
import type { AppOutletContext } from '@/components/AppLayout';
import type {
  Campaign,
  CampaignStatus,
  GovernmentLevel,
  CampaignsListResponse,
  CampaignsListParams,
  CreateCampaignPayload,
  UpdateCampaignPayload,
  Cut,
  ServicesConfig,
} from '@/types/api';
import CampaignEmailsDrawer from '@/pages/CampaignEmailsDrawer';
import ExportContactsModal from '@/components/canvass/ExportContactsModal';
import QrCodeModal from '@/components/QrCodeModal';
import { VideoPickerModal } from '@/components/media/VideoPickerModal';
import type { Video } from '@/components/media/VideoPickerModal';
import { useSettingsStore } from '@/stores/settings.store';
import { PageTour } from '@/components/tour/PageTour';

const { TextArea } = Input;

function CoverVideoField({ video, onChoose, onRemove, target }: {
  video: Video | null;
  onChoose: (target: 'create' | 'edit') => void;
  onRemove: (target: 'create' | 'edit') => void;
  target: 'create' | 'edit';
}) {
  if (video) {
    return (
      <Space>
        <Tag color="blue">Video #{video.id}: {video.title}</Tag>
        <Button size="small" danger onClick={() => onRemove(target)}>Remove</Button>
      </Space>
    );
  }
  return <Button size="small" onClick={() => onChoose(target)}>Choose Cover Video</Button>;
}

const statusColors: Record<CampaignStatus, string> = {
  DRAFT: 'default',
  ACTIVE: 'green',
  PAUSED: 'orange',
  ARCHIVED: 'gray',
};

const statusOptions: { value: CampaignStatus; label: string }[] = [
  { value: 'DRAFT', label: 'Draft' },
  { value: 'ACTIVE', label: 'Active' },
  { value: 'PAUSED', label: 'Paused' },
  { value: 'ARCHIVED', label: 'Archived' },
];

const govLevelOptions: { value: GovernmentLevel; label: string }[] = [
  { value: 'FEDERAL', label: 'Federal' },
  { value: 'PROVINCIAL', label: 'Provincial' },
  { value: 'MUNICIPAL', label: 'Municipal' },
  { value: 'SCHOOL_BOARD', label: 'School Board' },
];

const govLevelColors: Record<GovernmentLevel, string> = {
  FEDERAL: 'blue',
  PROVINCIAL: 'purple',
  MUNICIPAL: 'cyan',
  SCHOOL_BOARD: 'magenta',
};

export default function CampaignsPage() {
  const [campaigns, setCampaigns] = useState<Campaign[]>([]);
  const [pagination, setPagination] = useState({ page: 1, limit: 20, total: 0, totalPages: 0 });
  const [loading, setLoading] = useState(false);
  const [search, setSearch] = useState('');
  const [debouncedSearch, setDebouncedSearch] = useState('');
  const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
  const [statusFilter, setStatusFilter] = useState<CampaignStatus | undefined>();
  const [createModalOpen, setCreateModalOpen] = useState(false);
  const [editModalOpen, setEditModalOpen] = useState(false);
  const [editingCampaign, setEditingCampaign] = useState<Campaign | null>(null);
  const [emailsDrawerOpen, setEmailsDrawerOpen] = useState(false);
  const [emailsCampaign, setEmailsCampaign] = useState<Campaign | null>(null);
  const [exportOpen, setExportOpen] = useState(false);
  const [exportCampaignId, setExportCampaignId] = useState<string | undefined>();
  const [cuts, setCuts] = useState<Cut[]>([]);
  const [qrCampaign, setQrCampaign] = useState<Campaign | null>(null);
  const [createForm] = Form.useForm();
  const [editForm] = Form.useForm();
  const [videoPickerOpen, setVideoPickerOpen] = useState(false);
  const [videoPickerTarget, setVideoPickerTarget] = useState<'create' | 'edit'>('create');
  const [createSelectedVideo, setCreateSelectedVideo] = useState<Video | null>(null);
  const [editSelectedVideo, setEditSelectedVideo] = useState<Video | null>(null);
  const { settings: siteSettings } = useSettingsStore();
  const { user: currentUser } = useAuthStore();
  const isSuperAdmin = currentUser?.role === 'SUPER_ADMIN';
  const [nocodbUrl, setNocodbUrl] = useState<string | null>(null);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  const handleSearchChange = (value: string) => {
    setSearch(value);
    clearTimeout(searchTimerRef.current);
    searchTimerRef.current = setTimeout(() => setDebouncedSearch(value), 300);
  };

  useEffect(() => {
    return () => clearTimeout(searchTimerRef.current);
  }, []);

  const fetchCampaigns = useCallback(async (params?: CampaignsListParams) => {
    setLoading(true);
    try {
      const { data } = await api.get<CampaignsListResponse>('/campaigns', {
        params: {
          page: params?.page ?? pagination.page,
          limit: params?.limit ?? pagination.limit,
          search: params?.search ?? (debouncedSearch || undefined),
          status: params?.status ?? statusFilter,
        },
      });
      setCampaigns(data.campaigns);
      setPagination(data.pagination);
    } catch {
      message.error('Failed to load campaigns');
    } finally {
      setLoading(false);
    }
  }, [pagination.page, pagination.limit, debouncedSearch, statusFilter]);

  useEffect(() => {
    fetchCampaigns({ page: 1 });
  }, [debouncedSearch, statusFilter]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleTableChange = (pag: TablePaginationConfig) => {
    fetchCampaigns({ page: pag.current ?? 1, limit: pag.pageSize ?? 20 });
  };

  const handleCreate = async (values: CreateCampaignPayload) => {
    try {
      await api.post('/campaigns', { ...values, coverVideoId: createSelectedVideo?.id ?? null });
      message.success('Campaign created');
      setCreateModalOpen(false);
      createForm.resetFields();
      setCreateSelectedVideo(null);
      fetchCampaigns({ page: 1 });
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || 'Failed to create campaign';
      message.error(msg);
    }
  };

  const handleEdit = async (values: UpdateCampaignPayload) => {
    if (!editingCampaign) return;
    try {
      await api.put(`/campaigns/${editingCampaign.id}`, { ...values, coverVideoId: editSelectedVideo?.id ?? null });
      message.success('Campaign updated');
      setEditModalOpen(false);
      setEditingCampaign(null);
      editForm.resetFields();
      setEditSelectedVideo(null);
      fetchCampaigns();
    } catch (err: unknown) {
      const msg =
        (err as { response?: { data?: { error?: { message?: string } } } })
          ?.response?.data?.error?.message || 'Failed to update campaign';
      message.error(msg);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/campaigns/${id}`);
      message.success('Campaign deleted');
      fetchCampaigns();
    } catch {
      message.error('Failed to delete campaign');
    }
  };

  const openExport = useCallback((campaignId: string) => {
    setExportCampaignId(campaignId);
    setExportOpen(true);
    if (cuts.length === 0) {
      api.get('/map/cuts', { params: { limit: 100 } })
        .then(({ data }) => setCuts(data.cuts ?? data))
        .catch(() => {});
    }
  }, [cuts.length]);

  const openEdit = (campaign: Campaign) => {
    setEditingCampaign(campaign);
    editForm.setFieldsValue({
      title: campaign.title,
      description: campaign.description,
      emailSubject: campaign.emailSubject,
      emailBody: campaign.emailBody,
      callToAction: campaign.callToAction,
      status: campaign.status,
      targetGovernmentLevels: campaign.targetGovernmentLevels,
      allowSmtpEmail: campaign.allowSmtpEmail,
      allowMailtoLink: campaign.allowMailtoLink,
      collectUserInfo: campaign.collectUserInfo,
      showEmailCount: campaign.showEmailCount,
      showCallCount: campaign.showCallCount,
      allowEmailEditing: campaign.allowEmailEditing,
      allowCustomRecipients: campaign.allowCustomRecipients,
      showResponseWall: campaign.showResponseWall,
      highlightCampaign: campaign.highlightCampaign,
      coverPhoto: campaign.coverPhoto,
      coverVideoId: campaign.coverVideoId,
    });
    setEditSelectedVideo(campaign.coverVideoId ? { id: campaign.coverVideoId, title: `Video #${campaign.coverVideoId}` } as Video : null);
    setEditModalOpen(true);
  };

  const columns: ColumnsType<Campaign> = [
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      render: (title: string, record: Campaign) => (
        <div>
          <Space>
            <span style={{ fontWeight: 500 }}>{title}</span>
            {record.highlightCampaign && <StarFilled style={{ color: '#faad14' }} />}
          </Space>
          <div style={{ fontSize: 12, color: 'rgba(255,255,255,0.45)' }}>/campaign/{record.slug}</div>
        </div>
      ),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      onHeaderCell: () => ({ 'data-tour-campaigns-status': true } as Record<string, unknown>),
      render: (status: CampaignStatus) => (
        <Tag color={statusColors[status]}>{status}</Tag>
      ),
    },
    {
      title: 'Gov. Levels',
      dataIndex: 'targetGovernmentLevels',
      key: 'targetGovernmentLevels',
      render: (levels: GovernmentLevel[]) =>
        levels.length > 0
          ? levels.map((l) => (
              <Tag key={l} color={govLevelColors[l]} style={{ fontSize: 11 }}>
                {l.replace('_', ' ')}
              </Tag>
            ))
          : '--',
      responsive: ['md'],
    },
    {
      title: 'Emails',
      key: 'emails',
      render: (_: unknown, record: Campaign) => record._count.emails,
      responsive: ['md'],
    },
    {
      title: 'Responses',
      key: 'responses',
      render: (_: unknown, record: Campaign) => record._count.responses,
      responsive: ['lg'],
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      key: 'createdAt',
      render: (date: string) => dayjs(date).format('YYYY-MM-DD'),
      responsive: ['md'],
    },
    {
      title: 'Actions',
      key: 'actions',
      onHeaderCell: () => ({ 'data-tour-campaigns-actions': true } as Record<string, unknown>),
      render: (_: unknown, record: Campaign) => (
        <Space>
          {record.status === 'ACTIVE' && (
            <Tooltip title="View public page">
              <Button
                type="link"
                size="small"
                icon={<EyeOutlined />}
                onClick={() => window.open(`/campaign/${record.slug}`, '_blank')}
              />
            </Tooltip>
          )}
          <Tooltip title="Copy public link">
            <Button
              type="link"
              size="small"
              icon={<LinkOutlined />}
              onClick={() => {
                const url = `${window.location.origin}/campaign/${record.slug}`;
                navigator.clipboard.writeText(url);
                message.success('Campaign link copied');
              }}
            />
          </Tooltip>
          <Tooltip title="View emails">
            <Button
              type="link"
              size="small"
              icon={<MailOutlined />}
              onClick={() => {
                setEmailsCampaign(record);
                setEmailsDrawerOpen(true);
              }}
            />
          </Tooltip>
          <Tooltip title="QR code">
            <Button
              type="link"
              size="small"
              icon={<QrcodeOutlined />}
              onClick={() => setQrCampaign(record)}
            />
          </Tooltip>
          <Tooltip title="Target from canvass">
            <Button
              type="link"
              size="small"
              icon={<ExportOutlined />}
              onClick={() => openExport(record.id)}
            />
          </Tooltip>
          <Tooltip title="Edit campaign">
            <Button
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={() => openEdit(record)}
            />
          </Tooltip>
          <Popconfirm
            title="Delete this campaign?"
            description="All associated emails and responses will also be deleted."
            onConfirm={() => handleDelete(record.id)}
          >
            <Tooltip title="Delete">
              <Button type="link" size="small" danger icon={<DeleteOutlined />} />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const campaignFormFields = (
    <>
      <Form.Item
        name="title"
        label="Title"
        rules={[{ required: true, message: 'Title is required' }]}
      >
        <Input placeholder="e.g. Save Our Local Library" />
      </Form.Item>
      <Form.Item name="description" label="Description">
        <TextArea rows={2} />
      </Form.Item>
      <Form.Item
        name="emailSubject"
        label="Email Subject"
        rules={[{ required: true, message: 'Email subject is required' }]}
      >
        <Input placeholder="e.g. Demand Action on Climate" />
      </Form.Item>
      <Form.Item
        name="emailBody"
        label="Email Body"
        rules={[{ required: true, message: 'Email body is required' }]}
      >
        <TextArea rows={4} />
      </Form.Item>
      <Form.Item name="callToAction" label="Call to Action">
        <TextArea rows={2} />
      </Form.Item>
      <Row gutter={12}>
        <Col span={12}>
          <Form.Item name="status" label="Status" initialValue="DRAFT">
            <Select options={statusOptions} />
          </Form.Item>
        </Col>
        <Col span={12}>
          <Form.Item name="targetGovernmentLevels" label="Government Levels" initialValue={[]}>
            <Select mode="multiple" options={govLevelOptions} />
          </Form.Item>
        </Col>
      </Row>
      <Form.Item name="coverPhoto" label="Cover Photo URL">
        <Input placeholder="https://..." />
      </Form.Item>

      {siteSettings?.enableMediaFeatures !== false && (
        <Form.Item label="Cover Video">
          <CoverVideoField
            video={videoPickerTarget === 'create' ? createSelectedVideo : editSelectedVideo}
            onChoose={(target) => { setVideoPickerTarget(target); setVideoPickerOpen(true); }}
            onRemove={(target) => {
              if (target === 'create') { setCreateSelectedVideo(null); createForm.setFieldsValue({ coverVideoId: null }); }
              else { setEditSelectedVideo(null); editForm.setFieldsValue({ coverVideoId: null }); }
            }}
            target={editModalOpen ? 'edit' : 'create'}
          />
        </Form.Item>
      )}

      <Divider orientation="left" plain>
        Campaign Options
      </Divider>
      <Row gutter={[16, 8]}>
        <Col xs={24} sm={12}>
          <Form.Item name="allowSmtpEmail" label={<span>Send Now (via server) <Tooltip title="Emails are sent directly through the platform's mail server on behalf of the user"><QuestionCircleOutlined style={{ color: 'rgba(255,255,255,0.35)' }} /></Tooltip></span>} valuePropName="checked" initialValue={true}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="allowMailtoLink" label={<span>Open in Email App <Tooltip title="Opens the user's default email app (Gmail, Outlook, etc.) with the message pre-filled"><QuestionCircleOutlined style={{ color: 'rgba(255,255,255,0.35)' }} /></Tooltip></span>} valuePropName="checked" initialValue={true}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="collectUserInfo" label="Collect User Info" valuePropName="checked" initialValue={true}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="showEmailCount" label="Show Email Count" valuePropName="checked" initialValue={true}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="showCallCount" label="Show Call Count" valuePropName="checked" initialValue={true}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="allowEmailEditing" label="Allow Email Editing" valuePropName="checked" initialValue={false}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="allowCustomRecipients" label="Allow Custom Recipients" valuePropName="checked" initialValue={false}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="showResponseWall" label="Show Response Wall" valuePropName="checked" initialValue={false}>
            <Switch />
          </Form.Item>
        </Col>
        <Col xs={24} sm={12}>
          <Form.Item name="highlightCampaign" label="Highlight Campaign" valuePropName="checked" initialValue={false}>
            <Switch />
          </Form.Item>
        </Col>
      </Row>
    </>
  );

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

  useEffect(() => {
    if (isSuperAdmin) {
      api.get<ServicesConfig>('/services/config')
        .then(({ data }) => setNocodbUrl(buildServiceUrl(data.nocodbSubdomain, data.domain, data.nocodbPort)))
        .catch(() => {});
    }
  }, [isSuperAdmin]);

  const headerActions = useMemo(() => (
    <Space>
      {isSuperAdmin && nocodbUrl && (
        <Tooltip title="Browse campaigns in NocoDB for advanced filtering & export">
          <Button icon={<DatabaseOutlined />} href={nocodbUrl} target="_blank" size="small">
            Browse in NocoDB
          </Button>
        </Tooltip>
      )}
      <Button
        icon={<MailOutlined />}
        onClick={() => navigate('/app/email-queue')}
      >
        Email Queue
      </Button>
    </Space>
  ), [navigate, isSuperAdmin, nocodbUrl]);

  useEffect(() => {
    setPageHeader({ title: 'Campaigns', actions: headerActions });
    return () => setPageHeader(null);
  }, [setPageHeader, headerActions]);

  const drawerOpen = createModalOpen || editModalOpen;
  const drawerWidth = isMobile ? 0 : 640;

  return (
    <>
      <div style={{ marginRight: drawerOpen ? drawerWidth : 0, transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)' }}>
        <Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
          <Col xs={24} sm={12} md={8}>
            <Input
              placeholder="Search by title or description"
              prefix={<SearchOutlined />}
              value={search}
              onChange={(e) => handleSearchChange(e.target.value)}
              allowClear
            />
          </Col>
          <Col xs={12} sm={7} md={4}>
            <Select
              placeholder="Status"
              options={statusOptions}
              value={statusFilter}
              onChange={setStatusFilter}
              allowClear
              style={{ width: '100%' }}
            />
          </Col>
          <Col flex="auto" style={{ textAlign: 'right' }}>
            <Button type="primary" icon={<PlusOutlined />} onClick={() => setCreateModalOpen(true)} data-tour-campaigns-create>
              Create Campaign
            </Button>
          </Col>
        </Row>

        <div data-tour-campaigns-table>
          <Table<Campaign>
            columns={columns}
            dataSource={campaigns}
            rowKey="id"
            loading={loading}
            pagination={{
              current: pagination.page,
              pageSize: pagination.limit,
              total: pagination.total,
              showSizeChanger: true,
              showTotal: (total) => `${total} campaigns`,
            }}
            onChange={handleTableChange}
            scroll={{ x: 'max-content' }}
            locale={{ emptyText: 'No campaigns yet. Create your first campaign to get started.' }}
          />
        </div>
      </div>

      {/* Create Drawer */}
      <Drawer
        title="Create Campaign"
        open={createModalOpen}
        destroyOnHidden
        mask={false}
        width={isMobile ? '100%' : 640}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setCreateModalOpen(false);
          createForm.resetFields();
          setCreateSelectedVideo(null);
        }}
        extra={
          <Space>
            <Button onClick={() => { setCreateModalOpen(false); createForm.resetFields(); setCreateSelectedVideo(null); }}>
              Cancel
            </Button>
            <Button type="primary" onClick={() => createForm.submit()}>
              Create
            </Button>
          </Space>
        }
      >
        <Form form={createForm} onFinish={handleCreate} layout="vertical">
          {campaignFormFields}
        </Form>
      </Drawer>

      {/* Edit Drawer */}
      <Drawer
        title="Edit Campaign"
        open={editModalOpen}
        destroyOnHidden
        mask={false}
        width={isMobile ? '100%' : 640}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => {
          setEditModalOpen(false);
          setEditingCampaign(null);
          editForm.resetFields();
          setEditSelectedVideo(null);
        }}
        extra={
          <Space>
            <Button onClick={() => { setEditModalOpen(false); setEditingCampaign(null); editForm.resetFields(); setEditSelectedVideo(null); }}>
              Cancel
            </Button>
            <Button type="primary" onClick={() => editForm.submit()}>
              Save
            </Button>
          </Space>
        }
      >
        <Form form={editForm} onFinish={handleEdit} layout="vertical">
          {campaignFormFields}
        </Form>
      </Drawer>

      {/* Emails Drawer */}
      <CampaignEmailsDrawer
        campaign={emailsCampaign}
        open={emailsDrawerOpen}
        onClose={() => {
          setEmailsDrawerOpen(false);
          setEmailsCampaign(null);
        }}
      />

      {/* QR Code Modal */}
      {qrCampaign && (
        <QrCodeModal
          open={!!qrCampaign}
          onClose={() => setQrCampaign(null)}
          url={`${window.location.origin}/campaign/${qrCampaign.slug}`}
          title={qrCampaign.title}
        />
      )}

      {/* Export Canvass Contacts Modal */}
      <ExportContactsModal
        open={exportOpen}
        onClose={() => { setExportOpen(false); setExportCampaignId(undefined); }}
        cuts={cuts}
        preselectedCampaignId={exportCampaignId}
      />

      {/* Video Picker Modal */}
      <VideoPickerModal
        open={videoPickerOpen}
        onClose={() => setVideoPickerOpen(false)}
        onSelect={(video: Video) => {
          if (videoPickerTarget === 'create') {
            setCreateSelectedVideo(video);
            createForm.setFieldsValue({ coverVideoId: video.id });
          } else {
            setEditSelectedVideo(video);
            editForm.setFieldsValue({ coverVideoId: video.id });
          }
          setVideoPickerOpen(false);
        }}
        title="Select Cover Video"
      />
      <PageTour sectionId="campaigns" />
    </>
  );
}
