import { useEffect, useState, useCallback } from 'react';
import {
  Card, Row, Col, Statistic, Table, Tag, Tabs, Select, DatePicker,
  Button, Space, Spin, App, Progress, Segmented, Typography, Grid, Empty,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  MailOutlined,
  TeamOutlined,
  MessageOutlined,
  RiseOutlined,
  ReloadOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import type { Dayjs } from 'dayjs';
import { useOutletContext } from 'react-router-dom';
import {
  BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer,
  PieChart, Pie, Cell, AreaChart, Area, Legend,
} from 'recharts';
import { api } from '@/lib/api';
import type { AppOutletContext } from '@/components/AppLayout';
import type {
  CampaignOverviewStats, CampaignEffectivenessRow,
  RepEffectivenessData, RepEffectivenessRow,
  GeoBreakdownData, GeoBreakdownRow,
  FunnelStage, ActivityTrendsData,
  CampaignStatus,
} from '@/types/api';
import {
  GOVERNMENT_LEVEL_COLORS,
  GOVERNMENT_LEVEL_LABELS,
} from '@/types/api';

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

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

const CHART_COLORS = ['#5B8FF9', '#5AD8A6', '#F6BD16', '#E86452', '#6DC8EC', '#945FB9'];
const LEVEL_PIE_COLORS: Record<string, string> = {
  FEDERAL: '#1890ff',
  PROVINCIAL: '#722ed1',
  MUNICIPAL: '#52c41a',
  SCHOOL_BOARD: '#fa8c16',
};

export default function CampaignEffectivenessPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { message } = App.useApp();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  // Filters
  const [campaignId, setCampaignId] = useState<string | undefined>();
  const [dateRange, setDateRange] = useState<[Dayjs | null, Dayjs | null] | null>(null);
  const [campaigns, setCampaigns] = useState<Array<{ id: string; title: string }>>([]);

  // Data
  const [overview, setOverview] = useState<CampaignOverviewStats | null>(null);
  const [repData, setRepData] = useState<RepEffectivenessData | null>(null);
  const [geoData, setGeoData] = useState<GeoBreakdownData | null>(null);
  const [funnelData, setFunnelData] = useState<FunnelStage[] | null>(null);
  const [trendsData, setTrendsData] = useState<ActivityTrendsData | null>(null);
  const [loading, setLoading] = useState(true);

  // Tab-specific controls
  const [geoGroupBy, setGeoGroupBy] = useState<'province' | 'city' | 'postalCode'>('province');
  const [trendGranularity, setTrendGranularity] = useState<'day' | 'week'>('day');
  const [activeTab, setActiveTab] = useState('performance');

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

  const buildParams = useCallback(() => {
    const params: Record<string, string> = {};
    if (campaignId) params.campaignId = campaignId;
    if (dateRange?.[0]) params.dateFrom = dateRange[0].toISOString();
    if (dateRange?.[1]) params.dateTo = dateRange[1].toISOString();
    return params;
  }, [campaignId, dateRange]);

  const loadAllData = useCallback(async () => {
    setLoading(true);
    try {
      const params = buildParams();
      const [overviewRes, repRes, geoRes, funnelRes, trendsRes] = await Promise.all([
        api.get('/influence/effectiveness/overview', { params }),
        api.get('/influence/effectiveness/representatives', { params: { ...params, limit: 50 } }),
        api.get('/influence/effectiveness/geographic', { params: { ...params, groupBy: geoGroupBy, limit: 30 } }),
        api.get('/influence/effectiveness/funnel', { params }),
        api.get('/influence/effectiveness/trends', { params: { ...params, granularity: trendGranularity } }),
      ]);

      setOverview(overviewRes.data);
      setRepData(repRes.data);
      setGeoData(geoRes.data);
      setFunnelData(funnelRes.data);
      setTrendsData(trendsRes.data);

      // Populate campaign dropdown from overview data
      if (overviewRes.data?.campaigns) {
        setCampaigns(overviewRes.data.campaigns.map((c: CampaignEffectivenessRow) => ({
          id: c.campaignId,
          title: c.title,
        })));
      }
    } catch {
      message.error('Failed to load effectiveness data');
    } finally {
      setLoading(false);
    }
  }, [buildParams, geoGroupBy, trendGranularity, message]);

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

  // Reload geographic data when groupBy changes
  const loadGeoData = useCallback(async (groupBy: string) => {
    try {
      const params = buildParams();
      const res = await api.get('/influence/effectiveness/geographic', {
        params: { ...params, groupBy, limit: 30 },
      });
      setGeoData(res.data);
    } catch {
      message.error('Failed to load geographic data');
    }
  }, [buildParams, message]);

  // Reload trends when granularity changes
  const loadTrendsData = useCallback(async (granularity: string) => {
    try {
      const params = buildParams();
      const res = await api.get('/influence/effectiveness/trends', {
        params: { ...params, granularity },
      });
      setTrendsData(res.data);
    } catch {
      message.error('Failed to load trends data');
    }
  }, [buildParams, message]);

  if (loading && !overview) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', padding: 100 }}>
        <Spin size="large" />
      </div>
    );
  }

  const { summary } = overview || { summary: { totalEmails: 0, totalResponses: 0, totalCalls: 0, activeCampaigns: 0, totalCampaigns: 0, avgResponseRate: 0 } };

  // --- Tab content components ---

  const performanceColumns: ColumnsType<CampaignEffectivenessRow> = [
    {
      title: 'Campaign',
      dataIndex: 'title',
      key: 'title',
      ellipsis: true,
      width: isMobile ? 150 : undefined,
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 90,
      render: (status: CampaignStatus) => (
        <Tag color={STATUS_COLORS[status]}>{status}</Tag>
      ),
    },
    {
      title: 'Emails',
      dataIndex: 'emailTotal',
      key: 'emailTotal',
      sorter: (a, b) => a.emailTotal - b.emailTotal,
      width: 90,
      align: 'right' as const,
    },
    {
      title: 'Responses',
      dataIndex: 'approvedResponses',
      key: 'approvedResponses',
      sorter: (a, b) => a.approvedResponses - b.approvedResponses,
      width: 100,
      align: 'right' as const,
    },
    {
      title: 'Calls',
      dataIndex: 'callCount',
      key: 'callCount',
      sorter: (a, b) => a.callCount - b.callCount,
      width: 80,
      align: 'right' as const,
    },
    {
      title: 'Response Rate',
      dataIndex: 'responseRate',
      key: 'responseRate',
      sorter: (a, b) => a.responseRate - b.responseRate,
      width: 140,
      render: (rate: number) => (
        <Progress
          percent={Math.round(rate * 100)}
          size="small"
          status={rate > 0.1 ? 'active' : 'normal'}
          strokeColor={rate > 0.1 ? '#52c41a' : undefined}
        />
      ),
    },
  ];

  const repColumns: ColumnsType<RepEffectivenessRow> = [
    {
      title: 'Representative',
      dataIndex: 'name',
      key: 'name',
      ellipsis: true,
      width: isMobile ? 150 : undefined,
    },
    {
      title: 'Level',
      dataIndex: 'level',
      key: 'level',
      width: 110,
      render: (level: string | null) => level ? (
        <Tag color={GOVERNMENT_LEVEL_COLORS[level as keyof typeof GOVERNMENT_LEVEL_COLORS]}>
          {GOVERNMENT_LEVEL_LABELS[level as keyof typeof GOVERNMENT_LEVEL_LABELS] || level}
        </Tag>
      ) : <Text type="secondary">-</Text>,
    },
    {
      title: 'Emails',
      dataIndex: 'emailsReceived',
      key: 'emailsReceived',
      sorter: (a, b) => a.emailsReceived - b.emailsReceived,
      width: 90,
      align: 'right' as const,
    },
    {
      title: 'Responses',
      dataIndex: 'responsesGiven',
      key: 'responsesGiven',
      sorter: (a, b) => a.responsesGiven - b.responsesGiven,
      width: 100,
      align: 'right' as const,
    },
    {
      title: 'Verified',
      dataIndex: 'verifiedCount',
      key: 'verifiedCount',
      width: 90,
      align: 'right' as const,
    },
    {
      title: 'Rate',
      dataIndex: 'responseRate',
      key: 'responseRate',
      sorter: (a, b) => a.responseRate - b.responseRate,
      width: 120,
      render: (rate: number) => (
        <Progress
          percent={Math.round(rate * 100)}
          size="small"
          strokeColor={rate > 0.2 ? '#52c41a' : rate > 0 ? '#faad14' : undefined}
        />
      ),
    },
  ];

  const geoColumns: ColumnsType<GeoBreakdownRow> = [
    {
      title: geoGroupBy === 'postalCode' ? 'Postal Code' : geoGroupBy === 'city' ? 'City' : 'Province',
      dataIndex: 'key',
      key: 'key',
    },
    {
      title: 'Emails',
      dataIndex: 'emailCount',
      key: 'emailCount',
      sorter: (a, b) => a.emailCount - b.emailCount,
      width: 100,
      align: 'right' as const,
    },
    ...(geoGroupBy === 'postalCode' ? [
      {
        title: 'City',
        dataIndex: 'city',
        key: 'city',
        render: (v: string | null) => v || <Text type="secondary">-</Text>,
      },
      {
        title: 'Province',
        dataIndex: 'province',
        key: 'province',
        render: (v: string | null) => v || <Text type="secondary">-</Text>,
      },
    ] as ColumnsType<GeoBreakdownRow> : []),
  ];

  // Top 10 campaigns for bar chart
  const top10Campaigns = (overview?.campaigns || [])
    .sort((a, b) => b.emailTotal - a.emailTotal)
    .slice(0, 10)
    .map((c) => ({
      name: c.title.length > 25 ? c.title.substring(0, 22) + '...' : c.title,
      emails: c.emailTotal,
      responses: c.approvedResponses,
    }));

  // Funnel bar data
  const funnelChartData = (funnelData || []).map((stage) => ({
    name: stage.name,
    count: stage.count,
    percent: Math.round(stage.percentOfFirst * 100),
    fill: CHART_COLORS[0],
  }));

  return (
    <div style={{ padding: isMobile ? 12 : 0 }}>
      {/* Filters */}
      <Card size="small" style={{ marginBottom: 16 }}>
        <Space wrap>
          <Select
            placeholder="All campaigns"
            allowClear
            style={{ minWidth: 220 }}
            value={campaignId}
            onChange={setCampaignId}
            options={campaigns.map((c) => ({ value: c.id, label: c.title }))}
            showSearch
            optionFilterProp="label"
          />
          <RangePicker
            value={dateRange as [Dayjs, Dayjs] | null}
            onChange={(v) => setDateRange(v)}
            format="YYYY-MM-DD"
          />
          <Button icon={<ReloadOutlined />} onClick={loadAllData} loading={loading}>
            Refresh
          </Button>
        </Space>
      </Card>

      {/* Summary stat cards */}
      <Row gutter={[16, 16]} style={{ marginBottom: 16 }}>
        <Col xs={12} sm={6}>
          <Card>
            <Statistic
              title="Total Emails"
              value={summary.totalEmails}
              prefix={<MailOutlined />}
            />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card>
            <Statistic
              title="Avg Response Rate"
              value={Math.round(summary.avgResponseRate * 100)}
              suffix="%"
              prefix={<RiseOutlined />}
              valueStyle={{ color: summary.avgResponseRate > 0.05 ? '#52c41a' : undefined }}
            />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card>
            <Statistic
              title="Total Responses"
              value={summary.totalResponses}
              prefix={<MessageOutlined />}
            />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card>
            <Statistic
              title="Active Campaigns"
              value={summary.activeCampaigns}
              suffix={`/ ${summary.totalCampaigns}`}
              prefix={<TeamOutlined />}
            />
          </Card>
        </Col>
      </Row>

      {/* Tabs */}
      <Card>
        <Tabs
          activeKey={activeTab}
          onChange={setActiveTab}
          items={[
            {
              key: 'performance',
              label: 'Performance',
              children: (
                <div>
                  {top10Campaigns.length > 0 ? (
                    <>
                      <Text strong style={{ display: 'block', marginBottom: 12 }}>
                        Top Campaigns by Email Volume
                      </Text>
                      <ResponsiveContainer width="100%" height={Math.max(250, top10Campaigns.length * 35)}>
                        <BarChart data={top10Campaigns} layout="vertical" margin={{ left: 10, right: 30 }}>
                          <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" />
                          <XAxis type="number" stroke="rgba(255,255,255,0.5)" />
                          <YAxis
                            type="category"
                            dataKey="name"
                            width={isMobile ? 100 : 180}
                            tick={{ fill: 'rgba(255,255,255,0.7)', fontSize: 12 }}
                          />
                          <Tooltip
                            contentStyle={{ background: '#1f1f1f', border: '1px solid #333' }}
                            labelStyle={{ color: '#fff' }}
                          />
                          <Bar dataKey="emails" fill="#5B8FF9" name="Emails" radius={[0, 4, 4, 0]} />
                          <Bar dataKey="responses" fill="#5AD8A6" name="Responses" radius={[0, 4, 4, 0]} />
                          <Legend />
                        </BarChart>
                      </ResponsiveContainer>
                    </>
                  ) : null}

                  <Text strong style={{ display: 'block', marginTop: 24, marginBottom: 12 }}>
                    All Campaigns
                  </Text>
                  <Table<CampaignEffectivenessRow>
                    dataSource={overview?.campaigns || []}
                    columns={performanceColumns}
                    rowKey="campaignId"
                    size="small"
                    scroll={{ x: 600 }}
                    pagination={{ pageSize: 15, showSizeChanger: false }}
                  />
                </div>
              ),
            },
            {
              key: 'representatives',
              label: 'Representatives',
              children: (
                <Row gutter={[16, 16]}>
                  {/* Pie chart - level distribution */}
                  {repData?.levelDistribution && repData.levelDistribution.length > 0 && (
                    <Col xs={24} lg={8}>
                      <Text strong style={{ display: 'block', marginBottom: 12 }}>
                        Responses by Government Level
                      </Text>
                      <ResponsiveContainer width="100%" height={280}>
                        <PieChart>
                          <Pie
                            data={repData.levelDistribution.map((d) => ({
                              name: GOVERNMENT_LEVEL_LABELS[d.level as keyof typeof GOVERNMENT_LEVEL_LABELS] || d.level,
                              value: d.count,
                            }))}
                            cx="50%"
                            cy="50%"
                            innerRadius={50}
                            outerRadius={100}
                            dataKey="value"
                            label={({ name, percent }) => `${name} ${((percent ?? 0) * 100).toFixed(0)}%`}
                          >
                            {repData.levelDistribution.map((d, i) => (
                              <Cell
                                key={d.level}
                                fill={LEVEL_PIE_COLORS[d.level] || CHART_COLORS[i % CHART_COLORS.length]}
                              />
                            ))}
                          </Pie>
                          <Tooltip
                            contentStyle={{ background: '#1f1f1f', border: '1px solid #333' }}
                          />
                        </PieChart>
                      </ResponsiveContainer>
                    </Col>
                  )}

                  {/* Rep table */}
                  <Col xs={24} lg={repData?.levelDistribution?.length ? 16 : 24}>
                    <Text strong style={{ display: 'block', marginBottom: 12 }}>
                      Representative Effectiveness ({repData?.totalRepresentatives || 0} total)
                    </Text>
                    <Table<RepEffectivenessRow>
                      dataSource={repData?.representatives || []}
                      columns={repColumns}
                      rowKey="name"
                      size="small"
                      scroll={{ x: 600 }}
                      pagination={{ pageSize: 15, showSizeChanger: false }}
                    />
                  </Col>
                </Row>
              ),
            },
            {
              key: 'geography',
              label: 'Geography',
              children: (
                <div>
                  <Space style={{ marginBottom: 16 }}>
                    <Segmented
                      value={geoGroupBy}
                      onChange={(v) => {
                        const val = v as 'province' | 'city' | 'postalCode';
                        setGeoGroupBy(val);
                        loadGeoData(val);
                      }}
                      options={[
                        { label: 'Province', value: 'province' },
                        { label: 'City', value: 'city' },
                        { label: 'Postal Code', value: 'postalCode' },
                      ]}
                    />
                  </Space>

                  {geoData?.data && geoData.data.length > 0 && geoGroupBy !== 'postalCode' ? (
                    <>
                      <ResponsiveContainer width="100%" height={Math.max(250, geoData.data.length * 30)}>
                        <BarChart data={geoData.data} layout="vertical" margin={{ left: 10, right: 30 }}>
                          <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" />
                          <XAxis type="number" stroke="rgba(255,255,255,0.5)" />
                          <YAxis
                            type="category"
                            dataKey="key"
                            width={isMobile ? 80 : 140}
                            tick={{ fill: 'rgba(255,255,255,0.7)', fontSize: 12 }}
                          />
                          <Tooltip
                            contentStyle={{ background: '#1f1f1f', border: '1px solid #333' }}
                            labelStyle={{ color: '#fff' }}
                          />
                          <Bar dataKey="emailCount" fill="#6DC8EC" name="Emails" radius={[0, 4, 4, 0]} />
                        </BarChart>
                      </ResponsiveContainer>
                    </>
                  ) : null}

                  <Table<GeoBreakdownRow>
                    dataSource={geoData?.data || []}
                    columns={geoColumns}
                    rowKey="key"
                    size="small"
                    scroll={{ x: 400 }}
                    pagination={{ pageSize: 20, showSizeChanger: false }}
                    style={{ marginTop: geoGroupBy !== 'postalCode' ? 16 : 0 }}
                  />

                  {geoData?.data?.length === 0 && (
                    <Empty description="No geographic data available" />
                  )}
                </div>
              ),
            },
            {
              key: 'funnel',
              label: 'Funnel',
              children: (
                <div>
                  <Text strong style={{ display: 'block', marginBottom: 16 }}>
                    Engagement Funnel
                  </Text>

                  {funnelData && funnelData.length > 0 ? (
                    <>
                      <ResponsiveContainer width="100%" height={300}>
                        <BarChart data={funnelChartData} margin={{ left: 10, right: 30 }}>
                          <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" />
                          <XAxis
                            dataKey="name"
                            stroke="rgba(255,255,255,0.5)"
                            tick={{ fill: 'rgba(255,255,255,0.7)', fontSize: 11 }}
                            angle={isMobile ? -30 : 0}
                            textAnchor={isMobile ? 'end' : 'middle'}
                            height={isMobile ? 60 : 30}
                          />
                          <YAxis stroke="rgba(255,255,255,0.5)" />
                          <Tooltip
                            contentStyle={{ background: '#1f1f1f', border: '1px solid #333' }}
                            labelStyle={{ color: '#fff' }}
                            formatter={(value: unknown, _name: unknown, props: unknown) => {
                              const v = value as number;
                              const p = props as { payload: { percent: number } };
                              return [`${v.toLocaleString()} (${p.payload.percent}%)`, 'Count'];
                            }}
                          />
                          <Bar dataKey="count" fill="#5B8FF9" radius={[4, 4, 0, 0]} />
                        </BarChart>
                      </ResponsiveContainer>

                      {/* Funnel stages detail */}
                      <Row gutter={[12, 12]} style={{ marginTop: 16 }}>
                        {funnelData.map((stage, i) => (
                          <Col xs={24} sm={12} md={8} lg={4} key={stage.name}>
                            <Card size="small">
                              <Statistic
                                title={stage.name}
                                value={stage.count}
                                suffix={
                                  i > 0 ? (
                                    <Text type="secondary" style={{ fontSize: 12 }}>
                                      ({Math.round(stage.percentOfFirst * 100)}%)
                                    </Text>
                                  ) : null
                                }
                              />
                              {i > 0 && stage.dropoff > 0 && (
                                <Text type="secondary" style={{ fontSize: 11 }}>
                                  {Math.round(stage.dropoff * 100)}% dropoff
                                </Text>
                              )}
                            </Card>
                          </Col>
                        ))}
                      </Row>
                    </>
                  ) : (
                    <Empty description="No funnel data available" />
                  )}
                </div>
              ),
            },
            {
              key: 'trends',
              label: 'Trends',
              children: (
                <div>
                  <Space style={{ marginBottom: 16 }}>
                    <Segmented
                      value={trendGranularity}
                      onChange={(v) => {
                        const val = v as 'day' | 'week';
                        setTrendGranularity(val);
                        loadTrendsData(val);
                      }}
                      options={[
                        { label: 'Daily', value: 'day' },
                        { label: 'Weekly', value: 'week' },
                      ]}
                    />
                  </Space>

                  {trendsData?.series && trendsData.series.length > 0 ? (
                    <ResponsiveContainer width="100%" height={350}>
                      <AreaChart data={trendsData.series} margin={{ left: 10, right: 30, top: 10 }}>
                        <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" />
                        <XAxis
                          dataKey="date"
                          stroke="rgba(255,255,255,0.5)"
                          tick={{ fill: 'rgba(255,255,255,0.7)', fontSize: 11 }}
                          tickFormatter={(d: string) => dayjs(d).format('MMM D')}
                        />
                        <YAxis stroke="rgba(255,255,255,0.5)" />
                        <Tooltip
                          contentStyle={{ background: '#1f1f1f', border: '1px solid #333' }}
                          labelStyle={{ color: '#fff' }}
                          labelFormatter={(d) => dayjs(String(d)).format('MMM D, YYYY')}
                        />
                        <Area
                          type="monotone"
                          dataKey="emails"
                          name="Emails Sent"
                          fill="#5B8FF9"
                          fillOpacity={0.3}
                          stroke="#5B8FF9"
                          strokeWidth={2}
                        />
                        <Area
                          type="monotone"
                          dataKey="responses"
                          name="Responses"
                          fill="#5AD8A6"
                          fillOpacity={0.3}
                          stroke="#5AD8A6"
                          strokeWidth={2}
                        />
                        <Legend />
                      </AreaChart>
                    </ResponsiveContainer>
                  ) : (
                    <Empty description="No trend data available for this period" />
                  )}

                  {trendsData && (
                    <Text type="secondary" style={{ display: 'block', marginTop: 8, fontSize: 12 }}>
                      Showing {trendsData.granularity} data from {dayjs(trendsData.dateFrom).format('MMM D, YYYY')} to {dayjs(trendsData.dateTo).format('MMM D, YYYY')}
                    </Text>
                  )}
                </div>
              ),
            },
          ]}
        />
      </Card>
    </div>
  );
}
