import { useEffect, useState, useCallback } from 'react';
import { Card, Row, Col, Statistic, Table, Tag, Typography, Spin, Progress, App, Button, Space, Grid } from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  HomeOutlined,
  TeamOutlined,
  ThunderboltOutlined,
  CheckCircleOutlined,
  EnvironmentOutlined,
  HistoryOutlined,
  EyeOutlined,
  EyeInvisibleOutlined,
  ExportOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import { useOutletContext } from 'react-router-dom';
import { api } from '@/lib/api';
import type { AppOutletContext } from '@/components/AppLayout';
import type {
  CanvassAdminStats,
  CanvassVisit,
  VolunteerSummary,
  VisitOutcome,
} from '@/types/canvass';
import { VISIT_OUTCOME_LABELS, VISIT_OUTCOME_COLORS } from '@/types/canvass';
import type { PaginationMeta, Cut, MapSettings } from '@/types/api';
import type { SessionRoute } from '@/types/tracking';
import AdminLiveMap from '@/components/canvass/AdminLiveMap';
import HistoricalRoutesDrawer from '@/components/canvass/HistoricalRoutesDrawer';
import ExportContactsModal from '@/components/canvass/ExportContactsModal';
import CutCampaignAnalyticsCard from '@/components/canvass/CutCampaignAnalyticsCard';
import CanvassTrendsCard from '@/components/canvass/CanvassTrendsCard';

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

  const [stats, setStats] = useState<CanvassAdminStats | null>(null);
  const [activity, setActivity] = useState<CanvassVisit[]>([]);
  const [activityPagination, setActivityPagination] = useState<PaginationMeta | null>(null);
  const [volunteers, setVolunteers] = useState<VolunteerSummary[]>([]);
  const [cuts, setCuts] = useState<Cut[]>([]);
  const [mapSettings, setMapSettings] = useState<MapSettings | null>(null);
  const [loading, setLoading] = useState(true);
  const [mapVisible, setMapVisible] = useState(true);
  const [historyOpen, setHistoryOpen] = useState(false);
  const [_historyRoute, setHistoryRoute] = useState<SessionRoute | null>(null);
  const [visibleCutIds, setVisibleCutIds] = useState<Set<string>>(new Set());
  const [exportOpen, setExportOpen] = useState(false);
  const [exportPreselectedCuts, setExportPreselectedCuts] = useState<string[]>([]);

  useEffect(() => {
    setPageHeader({ title: 'Canvassing', fullBleed: true });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  const loadData = useCallback(async () => {
    try {
      const [statsRes, activityRes, volunteersRes, cutsRes, settingsRes] = await Promise.all([
        api.get('/map/canvass/stats'),
        api.get('/map/canvass/activity', { params: { limit: 10 } }),
        api.get('/map/canvass/volunteers'),
        api.get('/map/cuts', { params: { limit: 100 } }),
        api.get('/map/settings').catch(() => ({ data: null })),
      ]);
      setStats(statsRes.data);
      setActivity(activityRes.data.visits);
      setActivityPagination(activityRes.data.pagination);
      setVolunteers(volunteersRes.data);
      setCuts(cutsRes.data.cuts ?? cutsRes.data);
      if (settingsRes.data) setMapSettings(settingsRes.data);
    } catch {
      message.error('Failed to load canvass data');
    } finally {
      setLoading(false);
    }
  }, [message]);

  const toggleCut = useCallback((id: string) => {
    setVisibleCutIds((prev) => {
      const next = new Set(prev);
      if (next.has(id)) {
        next.delete(id);
      } else {
        next.add(id);
      }
      return next;
    });
  }, []);

  useEffect(() => {
    loadData();
    const interval = setInterval(loadData, 30000);
    return () => clearInterval(interval);
  }, [loadData]);

  // Initialize visible cuts when cuts data loads
  useEffect(() => {
    if (cuts.length > 0) {
      setVisibleCutIds(new Set(cuts.map((c) => c.id)));
    }
  }, [cuts]);

  const activityColumns: ColumnsType<CanvassVisit> = [
    {
      title: 'Volunteer',
      key: 'volunteer',
      ellipsis: true,
      render: (_: unknown, r: CanvassVisit) => r.user?.name || r.user?.email || '—',
    },
    {
      title: 'Address',
      key: 'address',
      ellipsis: true,
      render: (_: unknown, r: CanvassVisit) =>
        `${r.address?.location?.address ?? '?'}${r.address?.unitNumber ? ` #${r.address.unitNumber}` : ''}`,
    },
    {
      title: 'Outcome',
      dataIndex: 'outcome',
      key: 'outcome',
      width: 100,
      render: (val: VisitOutcome) => (
        <Tag color={VISIT_OUTCOME_COLORS[val]}>{VISIT_OUTCOME_LABELS[val]}</Tag>
      ),
    },
    {
      title: 'When',
      dataIndex: 'visitedAt',
      key: 'visitedAt',
      width: 80,
      responsive: ['md'] as any,
      render: (val: string) => dayjs(val).format('h:mm A'),
    },
  ];

  const volunteerColumns: ColumnsType<VolunteerSummary> = [
    {
      title: 'Name',
      key: 'name',
      ellipsis: true,
      render: (_: unknown, r: VolunteerSummary) => r.name || r.email,
    },
    { title: 'Visits', dataIndex: 'totalVisits', key: 'visits', width: 60, sorter: (a: VolunteerSummary, b: VolunteerSummary) => a.totalVisits - b.totalVisits },
    { title: 'Sessions', dataIndex: 'sessions', key: 'sessions', width: 70, responsive: ['md'] as any },
    {
      title: 'Last Active',
      dataIndex: 'lastActive',
      key: 'lastActive',
      width: 120,
      responsive: ['md'] as any,
      render: (val: string | null) => val ? dayjs(val).format('MMM D, h:mm A') : '—',
    },
  ];

  const cutColumns: ColumnsType<Cut> = [
    { title: 'Cut', dataIndex: 'name', key: 'name', ellipsis: true },
    {
      title: 'Progress',
      key: 'progress',
      width: 120,
      render: (_: unknown, r: Cut) => (
        <Progress
          percent={r.completionPercentage}
          size="small"
          style={{ maxWidth: 100 }}
        />
      ),
    },
    {
      title: 'Last Canvassed',
      dataIndex: 'lastCanvassed',
      key: 'lastCanvassed',
      width: 100,
      responsive: ['md'] as any,
      render: (val: string | null) => val ? dayjs(val).format('MMM D') : 'Never',
    },
  ];

  if (loading) {
    return <div style={{ textAlign: 'center', padding: 48 }}><Spin size="large" /></div>;
  }

  // Convert cuts to PublicCut shape for AdminLiveMap
  const publicCuts = cuts.map((c) => ({
    id: c.id,
    name: c.name,
    description: c.description,
    color: c.color,
    opacity: c.opacity,
    category: c.category,
    geojson: c.geojson,
    bounds: c.bounds,
  }));

  const mapHeight = isMobile ? 350 : isDesktop ? 'calc(100vh - 120px)' : 500;

  const mapCard = (
    <Card
      title={
        <Space>
          <EnvironmentOutlined />
          <span>Live Volunteer Map</span>
        </Space>
      }
      size="small"
      styles={{ body: { padding: 0 } }}
      extra={
        <Space>
          <Button
            size="small"
            icon={<ExportOutlined />}
            onClick={() => { setExportPreselectedCuts([]); setExportOpen(true); }}
          >
            Export to Campaign
          </Button>
          <Button
            size="small"
            icon={<HistoryOutlined />}
            onClick={() => setHistoryOpen(true)}
          >
            History
          </Button>
          <Button
            size="small"
            icon={mapVisible ? <EyeInvisibleOutlined /> : <EyeOutlined />}
            onClick={() => setMapVisible(!mapVisible)}
          >
            {mapVisible ? 'Hide' : 'Show'}
          </Button>
        </Space>
      }
    >
      {mapVisible && (
        <div style={{ height: mapHeight }}>
          <AdminLiveMap
            cuts={publicCuts}
            mapSettings={mapSettings}
            visibleCutIds={visibleCutIds}
            onToggleCut={toggleCut}
          />
        </div>
      )}
      {!mapVisible && (
        <Typography.Text type="secondary" style={{ display: 'block', textAlign: 'center', padding: '24px 0' }}>
          Map hidden to save resources. Click "Show" to enable.
        </Typography.Text>
      )}
    </Card>
  );

  const rightPanel = (
    <div
      style={
        isDesktop
          ? { position: 'sticky', top: 12, maxHeight: 'calc(100vh - 100px)', overflowY: 'auto', paddingRight: 4 }
          : undefined
      }
    >
      {/* Stats 2x2 grid */}
      <Row gutter={[8, 8]} style={{ marginBottom: 12 }}>
        <Col span={12}>
          <Card size="small">
            <Statistic title="Total Visits" value={stats?.totalVisits ?? 0} prefix={<HomeOutlined />} valueStyle={{ fontSize: 20 }} />
          </Card>
        </Col>
        <Col span={12}>
          <Card size="small">
            <Statistic title="Active Volunteers" value={stats?.activeVolunteers ?? 0} prefix={<TeamOutlined />} valueStyle={{ fontSize: 20 }} />
          </Card>
        </Col>
        <Col span={12}>
          <Card size="small">
            <Statistic title="Active Sessions" value={stats?.activeSessions ?? 0} prefix={<ThunderboltOutlined />} valueStyle={{ fontSize: 20 }} />
          </Card>
        </Col>
        <Col span={12}>
          <Card size="small">
            <Statistic title="Completion" value={stats?.overallCompletion ?? 0} suffix="%" prefix={<CheckCircleOutlined />} valueStyle={{ fontSize: 20 }} />
          </Card>
        </Col>
      </Row>

      <Card title="Recent Activity" size="small" style={{ marginBottom: 12 }}>
        <Table
          dataSource={activity}
          columns={activityColumns}
          rowKey="id"
          size="small"
          pagination={false}
          scroll={{ x: 'max-content' }}
          locale={{ emptyText: 'No activity recorded yet.' }}
        />
        {activityPagination && activityPagination.total > 10 && (
          <Typography.Text type="secondary" style={{ fontSize: 12, display: 'block', marginTop: 8 }}>
            Showing 10 of {activityPagination.total} visits
          </Typography.Text>
        )}
      </Card>

      <Card title="Cut Progress" size="small" style={{ marginBottom: 12 }}>
        <Table
          dataSource={cuts}
          columns={cutColumns}
          rowKey="id"
          size="small"
          pagination={false}
          scroll={{ x: 'max-content' }}
          locale={{ emptyText: 'No cuts assigned.' }}
        />
      </Card>

      <Card title="Volunteer Leaderboard" size="small" style={{ marginBottom: 12 }}>
        <Table
          dataSource={volunteers}
          columns={volunteerColumns}
          rowKey="userId"
          size="small"
          pagination={false}
          scroll={{ x: 'max-content' }}
          locale={{ emptyText: 'No sessions recorded yet.' }}
        />
      </Card>

      <CutCampaignAnalyticsCard
        onExportCut={(cutId) => {
          setExportPreselectedCuts([cutId]);
          setExportOpen(true);
        }}
      />
    </div>
  );

  return (
    <div style={{ padding: isMobile ? 8 : 12 }}>
      {isMobile ? (
        // Mobile: stack vertically
        <>
          {mapCard}
          <div style={{ marginTop: 16 }}>{rightPanel}</div>
        </>
      ) : (
        // Desktop/tablet: side-by-side
        <Row gutter={16}>
          <Col xs={24} md={13} lg={15}>
            {mapCard}
          </Col>
          <Col xs={24} md={11} lg={9}>
            {rightPanel}
          </Col>
        </Row>
      )}

      {/* Outcome Trends */}
      <div style={{ marginTop: 16, padding: isMobile ? '0' : undefined }}>
        <CanvassTrendsCard />
      </div>

      {/* Historical Routes Drawer */}
      <HistoricalRoutesDrawer
        open={historyOpen}
        onClose={() => setHistoryOpen(false)}
        onSelectRoute={setHistoryRoute}
        volunteers={volunteers.map((v) => ({ userId: v.userId, name: v.name, email: v.email }))}
      />

      {/* Export Contacts Modal */}
      <ExportContactsModal
        open={exportOpen}
        onClose={() => setExportOpen(false)}
        cuts={cuts}
        preselectedCutIds={exportPreselectedCuts}
      />
    </div>
  );
}
