import { useState, useEffect, useCallback } from 'react';
import {
  Table,
  Button,
  Tag,
  Switch,
  Space,
  Drawer,
  Form,
  Input,
  InputNumber,
  Select,
  Segmented,
  DatePicker,
  ColorPicker,
  Card,
  Statistic,
  Row,
  Col,
  Popconfirm,
  Modal,
  message,
  Typography,
  Spin,
  ConfigProvider,
  theme as antTheme,
  Grid,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  CopyOutlined,
  EyeOutlined,
  ThunderboltOutlined,
  PercentageOutlined,
  BarChartOutlined,
  PictureOutlined,
  CloseCircleOutlined,
} from '@ant-design/icons';
import { useOutletContext, useNavigate } from 'react-router-dom';
import { api } from '@/lib/api';
import type { AppOutletContext } from '@/types/api';
import type { GalleryAd, AdType, AdVisibility, AdPlacement } from '@/types/gallery-ads';
import { AD_TYPE_LABELS, AD_TYPE_COLORS, AD_VISIBILITY_LABELS, AD_VISIBILITY_COLORS, AD_PLACEMENT_LABELS } from '@/types/gallery-ads';
import FeatureGate from '@/components/FeatureGate';
import GalleryAdCard from '@/components/media/GalleryAdCard';
import PhotoPickerModal from '@/components/media/PhotoPickerModal';
import type { Photo } from '@/components/media/PhotoPickerModal';
import dayjs from 'dayjs';
import axios from 'axios';
import { getErrorMessage } from '@/utils/getErrorMessage';

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

interface DailyAnalytics {
  date: string;
  impressions: number;
  clicks: number;
}

interface AdAnalytics {
  daily: DailyAnalytics[];
  totals: {
    impressions: number;
    clicks: number;
    uniqueSessions: number;
    ctr: number;
  };
}

export default function GalleryAdsPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const navigate = useNavigate();
  const [ads, setAds] = useState<GalleryAd[]>([]);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const [loading, setLoading] = useState(true);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editingAd, setEditingAd] = useState<GalleryAd | null>(null);
  const [saving, setSaving] = useState(false);
  const [form] = Form.useForm();

  // Photo picker state
  const [photoPickerOpen, setPhotoPickerOpen] = useState(false);
  const watchedImagePath = Form.useWatch('imagePath', form);

  // Preview state
  const [previewAd, setPreviewAd] = useState<GalleryAd | null>(null);

  // Analytics drawer state
  const [analyticsAd, setAnalyticsAd] = useState<GalleryAd | null>(null);
  const [analytics, setAnalytics] = useState<AdAnalytics | null>(null);
  const [analyticsLoading, setAnalyticsLoading] = useState(false);

  useEffect(() => {
    setPageHeader({ title: 'Gallery Ads' });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  const fetchAds = useCallback(async () => {
    try {
      setLoading(true);
      const { data } = await api.get('/gallery-ads/admin', { params: { limit: 100 } });
      setAds(data.ads);
    } catch {
      message.error('Failed to load ads');
    } finally {
      setLoading(false);
    }
  }, []);

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

  const fetchAnalytics = useCallback(async (ad: GalleryAd) => {
    setAnalyticsAd(ad);
    setAnalyticsLoading(true);
    try {
      const { data } = await api.get(`/gallery-ads/admin/${ad.id}/analytics`, { params: { days: 30 } });
      setAnalytics(data);
    } catch {
      message.error('Failed to load analytics');
    } finally {
      setAnalyticsLoading(false);
    }
  }, []);

  const handleCreate = () => {
    setEditingAd(null);
    form.resetFields();
    form.setFieldsValue({
      type: 'custom',
      variant: 'standard',
      ctaStyle: 'primary',
      visibility: 'everyone',
      frequency: 6,
      position: 0,
      isActive: false,
      placements: [],
    });
    setDrawerOpen(true);
  };

  const handleEdit = (ad: GalleryAd) => {
    setEditingAd(ad);
    form.setFieldsValue({
      ...ad,
      placements: ad.placements || [],
      schedule: ad.startDate && ad.endDate
        ? [dayjs(ad.startDate), dayjs(ad.endDate)]
        : undefined,
    });
    setDrawerOpen(true);
  };

  const handleDuplicate = (ad: GalleryAd) => {
    setEditingAd(null);
    form.resetFields();
    form.setFieldsValue({
      ...ad,
      title: `${ad.title} (Copy)`,
      isActive: false,
      placements: ad.placements || [],
      schedule: ad.startDate && ad.endDate
        ? [dayjs(ad.startDate), dayjs(ad.endDate)]
        : undefined,
    });
    setDrawerOpen(true);
  };

  const handleSave = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);

      // Convert color picker value
      if (values.bgColor && typeof values.bgColor === 'object' && 'toHexString' in values.bgColor) {
        values.bgColor = values.bgColor.toHexString();
      }

      // Convert schedule to startDate/endDate
      if (values.schedule) {
        values.startDate = values.schedule[0].toISOString();
        values.endDate = values.schedule[1].toISOString();
      } else {
        values.startDate = null;
        values.endDate = null;
      }
      delete values.schedule;

      if (editingAd) {
        await api.put(`/gallery-ads/admin/${editingAd.id}`, values);
        message.success('Ad updated');
      } else {
        await api.post('/gallery-ads/admin', values);
        message.success('Ad created');
      }

      setDrawerOpen(false);
      fetchAds();
    } catch (err: unknown) {
      if (axios.isAxiosError(err) && err.response?.data?.error) {
        message.error(err.response.data.error);
      } else if (!(err instanceof Object && 'errorFields' in err)) {
        message.error('Failed to save ad');
      }
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await api.delete(`/gallery-ads/admin/${id}`);
      message.success('Ad deleted');
      fetchAds();
    } catch (err: unknown) {
      message.error(getErrorMessage(err, 'Failed to delete ad'));
    }
  };

  const handleToggleActive = async (id: number, isActive: boolean) => {
    try {
      await api.put(`/gallery-ads/admin/${id}`, { isActive });
      setAds(prev => prev.map(a => a.id === id ? { ...a, isActive } : a));
    } catch {
      message.error('Failed to update ad status');
    }
  };

  // Stats
  const totalAds = ads.length;
  const activeAds = ads.filter(a => a.isActive).length;
  const totalImpressions = ads.reduce((sum, a) => sum + (a.impressionCount || 0), 0);
  const totalClicks = ads.reduce((sum, a) => sum + (a.clickCount || 0), 0);

  const columns = [
    {
      title: 'Type',
      dataIndex: 'type',
      key: 'type',
      width: 110,
      render: (type: AdType) => (
        <Tag color={AD_TYPE_COLORS[type]}>{AD_TYPE_LABELS[type]}</Tag>
      ),
    },
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      ellipsis: true,
      render: (title: string, record: GalleryAd) => (
        <div>
          <div>{title}</div>
          {record.isSystemAd && <Text type="secondary" style={{ fontSize: 11 }}>System</Text>}
          {record.productId && (
            <Tag
              color="cyan"
              style={{ fontSize: 10, marginTop: 2, cursor: 'pointer' }}
              onClick={() => navigate(`/app/payments/products?highlight=${record.productId}`)}
            >
              Auto (Product)
            </Tag>
          )}
        </div>
      ),
    },
    {
      title: 'Visibility',
      dataIndex: 'visibility',
      key: 'visibility',
      width: 130,
      render: (vis: AdVisibility) => (
        <Tag color={AD_VISIBILITY_COLORS[vis]}>{AD_VISIBILITY_LABELS[vis]}</Tag>
      ),
    },
    {
      title: 'Placements',
      dataIndex: 'placements',
      key: 'placements',
      width: 160,
      render: (placements: AdPlacement[]) => {
        if (!placements || placements.length === 0) {
          return <Tag>All Pages</Tag>;
        }
        return (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 2 }}>
            {placements.slice(0, 3).map((p) => (
              <Tag key={p} style={{ fontSize: 11 }}>{AD_PLACEMENT_LABELS[p] || p}</Tag>
            ))}
            {placements.length > 3 && <Tag style={{ fontSize: 11 }}>+{placements.length - 3}</Tag>}
          </div>
        );
      },
    },
    {
      title: 'Frequency',
      dataIndex: 'frequency',
      key: 'frequency',
      width: 100,
      render: (freq: number) => `Every ${freq}`,
    },
    {
      title: 'Impressions',
      dataIndex: 'impressionCount',
      key: 'impressionCount',
      width: 100,
      render: (count: number) => (count || 0).toLocaleString(),
    },
    {
      title: 'Clicks',
      dataIndex: 'clickCount',
      key: 'clickCount',
      width: 80,
      render: (count: number) => (count || 0).toLocaleString(),
    },
    {
      title: 'CTR',
      key: 'ctr',
      width: 70,
      render: (_: unknown, record: GalleryAd) => {
        const impressions = record.impressionCount || 0;
        const clicks = record.clickCount || 0;
        if (impressions === 0) return '-';
        return `${((clicks / impressions) * 100).toFixed(1)}%`;
      },
    },
    {
      title: 'Active',
      dataIndex: 'isActive',
      key: 'isActive',
      width: 80,
      render: (active: boolean, record: GalleryAd) => (
        <Switch
          checked={active}
          size="small"
          onChange={(checked) => handleToggleActive(record.id, checked)}
        />
      ),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 160,
      render: (_: unknown, record: GalleryAd) => (
        <Space size="small">
          <Button type="text" size="small" icon={<EyeOutlined />} onClick={() => setPreviewAd(record)} title="Preview" />
          <Button type="text" size="small" icon={<BarChartOutlined />} onClick={() => fetchAnalytics(record)} title="Analytics" />
          <Button type="text" size="small" icon={<EditOutlined />} onClick={() => handleEdit(record)} />
          <Button type="text" size="small" icon={<CopyOutlined />} onClick={() => handleDuplicate(record)} />
          {!record.isSystemAd && (
            <Popconfirm title="Delete this ad?" onConfirm={() => handleDelete(record.id)}>
              <Button type="text" size="small" danger icon={<DeleteOutlined />} />
            </Popconfirm>
          )}
        </Space>
      ),
    },
  ];

  const activeDrawerWidth = !isMobile && drawerOpen ? 520 : 0;

  return (
    <FeatureGate feature="enableGalleryAds">
      <div
        style={{
          marginRight: activeDrawerWidth,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
      <div style={{ marginBottom: 16, display: 'flex', gap: 8 }}>
        <Button type="primary" icon={<PlusOutlined />} onClick={handleCreate}>
          Create Ad
        </Button>
        <Button icon={<BarChartOutlined />} onClick={() => navigate('/app/payments/ads/analytics')}>
          Analytics
        </Button>
      </div>

      <Row gutter={16} style={{ marginBottom: 24 }}>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic title="Total Ads" value={totalAds} prefix={<EyeOutlined />} />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic title="Active" value={activeAds} prefix={<ThunderboltOutlined />} valueStyle={{ color: '#52c41a' }} />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic title="Impressions" value={totalImpressions} prefix={<EyeOutlined />} />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic title="Clicks" value={totalClicks} prefix={<PercentageOutlined />} />
          </Card>
        </Col>
      </Row>

      <Table
        dataSource={ads}
        columns={columns}
        scroll={{ x: 'max-content' }}
        rowKey="id"
        loading={loading}
        pagination={false}
        size="middle"
      />

      </div>

      {/* Edit/Create Drawer */}
      <Drawer
        title={editingAd ? 'Edit Ad' : 'Create Ad'}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        width={isMobile ? '100%' : 520}
        mask={false}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        extra={
          <Button type="primary" onClick={handleSave} loading={saving}>
            Save
          </Button>
        }
      >
        <Form form={form} layout="vertical">
          <Form.Item name="type" label="Type" rules={[{ required: true }]}>
            <Select
              disabled={editingAd?.isSystemAd}
              options={[
                { label: 'System', value: 'system' },
                { label: 'Subscribe', value: 'payment_subscribe' },
                { label: 'Donate', value: 'payment_donate' },
                { label: 'Shop', value: 'payment_shop' },
                { label: 'Custom', value: 'custom' },
              ]}
            />
          </Form.Item>

          <Form.Item name="variant" label="Variant">
            <Segmented
              options={[
                { label: 'Standard', value: 'standard' },
                { label: 'Highlight', value: 'highlight' },
                { label: 'Minimal', value: 'minimal' },
              ]}
            />
          </Form.Item>

          <Form.Item name="title" label="Title" rules={[{ required: true }]}>
            <Input />
          </Form.Item>

          <Form.Item name="subtitle" label="Subtitle">
            <TextArea rows={2} />
          </Form.Item>

          <Form.Item name="linkUrl" label="Link URL">
            <Input placeholder="/campaigns or https://..." />
          </Form.Item>

          <Form.Item name="ctaText" label="CTA Button Text">
            <Input placeholder="Learn More" />
          </Form.Item>

          <Form.Item name="ctaStyle" label="CTA Style">
            <Segmented
              options={[
                { label: 'Primary', value: 'primary' },
                { label: 'Outline', value: 'outline' },
                { label: 'Link', value: 'link' },
              ]}
            />
          </Form.Item>

          <Form.Item name="bgColor" label="Background Color">
            <ColorPicker />
          </Form.Item>

          <Form.Item name="iconEmoji" label="Icon/Emoji">
            <Input placeholder="e.g. megaphone icon or emoji" maxLength={10} />
          </Form.Item>

          <Form.Item name="imagePath" label="Image">
            <Input
              readOnly
              placeholder="Select an image..."
              addonAfter={
                <Space size={4}>
                  <PictureOutlined
                    style={{ cursor: 'pointer' }}
                    onClick={() => setPhotoPickerOpen(true)}
                    title="Browse photos"
                  />
                  {watchedImagePath && (
                    <CloseCircleOutlined
                      style={{ cursor: 'pointer', color: '#ff4d4f' }}
                      onClick={() => form.setFieldsValue({ imagePath: null })}
                      title="Clear image"
                    />
                  )}
                </Space>
              }
              onClick={() => setPhotoPickerOpen(true)}
              style={{ cursor: 'pointer' }}
            />
          </Form.Item>
          {watchedImagePath && (
            <div style={{ marginBottom: 16, textAlign: 'center' }}>
              <img
                src={watchedImagePath}
                alt="Ad image preview"
                style={{ maxHeight: 160, maxWidth: '100%', borderRadius: 8, objectFit: 'cover' }}
              />
            </div>
          )}

          <Form.Item name="visibility" label="Visibility">
            <Select
              options={[
                { label: 'Everyone', value: 'everyone' },
                { label: 'Anonymous Only', value: 'anonymous' },
                { label: 'Logged-In Only', value: 'authenticated' },
                { label: 'Non-Subscribers', value: 'non_subscriber' },
              ]}
            />
          </Form.Item>

          <Form.Item
            name="placements"
            label="Placements"
            extra="Leave empty to show on all pages"
          >
            <Select
              mode="multiple"
              placeholder="All pages"
              options={Object.entries(AD_PLACEMENT_LABELS).map(([value, label]) => ({
                label,
                value,
              }))}
              allowClear
            />
          </Form.Item>

          <Row gutter={16}>
            <Col span={12}>
              <Form.Item name="frequency" label="Frequency" extra="Insert every N videos" rules={[{ required: true }]}>
                <InputNumber min={1} max={24} style={{ width: '100%' }} />
              </Form.Item>
            </Col>
            <Col span={12}>
              <Form.Item name="position" label="Priority" extra="Lower = higher priority">
                <InputNumber min={0} style={{ width: '100%' }} />
              </Form.Item>
            </Col>
          </Row>

          <Form.Item name="isActive" label="Active" valuePropName="checked">
            <Switch />
          </Form.Item>

          <Form.Item name="schedule" label="Schedule (optional)">
            <RangePicker
              showTime
              style={{ width: '100%' }}
              placeholder={['Start Date', 'End Date']}
            />
          </Form.Item>
        </Form>
      </Drawer>

      {/* Preview Modal — renders GalleryAdCard on dark gallery background */}
      <Modal
        open={!!previewAd}
        onCancel={() => setPreviewAd(null)}
        footer={null}
        width={isMobile ? '95vw' : 360}
        styles={{ content: { background: '#0d1b2a', padding: 24 } }}
      >
        {previewAd && (
          <ConfigProvider
            theme={{
              algorithm: antTheme.darkAlgorithm,
              token: {
                colorBgBase: '#0d1b2a',
                colorBgContainer: '#1b2838',
              },
            }}
          >
            <GalleryAdCard ad={previewAd} preview />
          </ConfigProvider>
        )}
      </Modal>

      {/* Photo Picker Modal */}
      <PhotoPickerModal
        open={photoPickerOpen}
        onClose={() => setPhotoPickerOpen(false)}
        onSelect={(photo: Photo) => {
          const url = photo.thumbnailUrl || `/media/photos/${photo.id}/thumbnail`;
          form.setFieldsValue({ imagePath: url });
        }}
        mode="single"
        title="Select Ad Image"
      />

      {/* Analytics Drawer */}
      <Drawer
        title={analyticsAd ? `Analytics: ${analyticsAd.title}` : 'Ad Analytics'}
        open={!!analyticsAd}
        onClose={() => { setAnalyticsAd(null); setAnalytics(null); }}
        width={isMobile ? '100%' : 520}
        mask={false}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
      >
        {analyticsLoading ? (
          <div style={{ textAlign: 'center', padding: 48 }}><Spin /></div>
        ) : analytics ? (
          <>
            <Row gutter={16} style={{ marginBottom: 24 }}>
              <Col span={6}>
                <Statistic title="Impressions" value={analytics.totals.impressions} />
              </Col>
              <Col span={6}>
                <Statistic title="Clicks" value={analytics.totals.clicks} />
              </Col>
              <Col span={6}>
                <Statistic title="CTR" value={analytics.totals.ctr} suffix="%" />
              </Col>
              <Col span={6}>
                <Statistic title="Unique Sessions" value={analytics.totals.uniqueSessions} />
              </Col>
            </Row>

            <Text strong style={{ display: 'block', marginBottom: 12 }}>Daily Breakdown (Last 30 Days)</Text>
            {analytics.daily.length === 0 ? (
              <Text type="secondary">No data recorded yet</Text>
            ) : (
              <Table
                dataSource={analytics.daily}
                scroll={{ x: 'max-content' }}
                rowKey="date"
                pagination={false}
                size="small"
                columns={[
                  { title: 'Date', dataIndex: 'date', key: 'date' },
                  { title: 'Impressions', dataIndex: 'impressions', key: 'impressions' },
                  { title: 'Clicks', dataIndex: 'clicks', key: 'clicks' },
                  {
                    title: 'CTR',
                    key: 'ctr',
                    render: (_: unknown, row: DailyAnalytics) =>
                      row.impressions > 0
                        ? `${((row.clicks / row.impressions) * 100).toFixed(1)}%`
                        : '-',
                  },
                ]}
              />
            )}
          </>
        ) : null}
      </Drawer>
    </FeatureGate>
  );
}
