"use client";
import {
  Page,
  LegacyCard,
  Text,
  InlineStack,
  BlockStack,
  Badge,
  Icon,
  Button,
  ButtonGroup,
  ChoiceList,
  TextField,
  Spinner,
  Popover,
  ActionList,
  Divider,
  Box,
  InlineGrid,
  ProgressBar,
} from '@shopify/polaris';
import {
  ArrowLeftIcon,
  RefreshIcon,
  CartIcon,
  CashDollarIcon,
  ChartVerticalIcon,
  FilterIcon,
  XIcon,
} from '@shopify/polaris-icons';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate } from '@remix-run/react';
import { fetchAbandonedAnalyticsSummary } from '../utils/abandonedCartApi';
import { useApiFeedback } from '../utils/useApiFeedback';

const DATE_PRESETS = [
  { label: 'All Upto Date', value: 'all' },
  { label: 'Today', value: 'today' },
  { label: 'Yesterday', value: 'yesterday' },
  { label: 'Last 7 days', value: 'last_7_days' },
  { label: 'Last 30 days', value: 'last_30_days' },
  { label: 'Last 90 days', value: 'last_90_days' },
];

const PLATFORMS = [
  { label: 'Shopify', value: 'Shopify' },
  { label: 'GoKwik', value: 'GoKwik' },
  { label: 'Shiprocket', value: 'Shiprocket' },
  { label: 'Shopflo', value: 'Shopflo' },
  { label: 'Razorpay Magic Checkout', value: 'razorpaymagiccheckout' },
  { label: 'Cashfree', value: 'CashFree' },
  { label: 'Shipway', value: 'Shipway' },
];

const STATUS_OPTIONS = [
  { label: 'Abandoned Yet', value: '0' },
  { label: 'Recovered', value: '1' },
  { label: 'Chat Closed', value: '2' },
  { label: 'Message Sent', value: '3' },
];

function StatCard({ title, value, subtitle, icon, accent, loading }) {
  return (
    <LegacyCard>
      <Box padding="400">
        <InlineStack gap="300" blockAlign="center" wrap={false}>
          <Box
            padding="200"
            style={{
              background: accent.iconBg,
              borderRadius: '8px',
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              width: 40,
              height: 40,
            }}
          >
            <Icon source={icon} tone={accent.iconTone} />
          </Box>
          <BlockStack gap="050">
            <Text variant="bodySm" tone="subdued" as="p">{title}</Text>
            {loading ? (
              <Spinner accessibilityLabel={`Loading ${title}`} size="small" />
            ) : (
              <Text variant="heading2xl" as="p">{value}</Text>
            )}
            {subtitle ? (
              <Text variant="bodySm" tone="subdued" as="p">{subtitle}</Text>
            ) : null}
          </BlockStack>
        </InlineStack>
      </Box>
    </LegacyCard>
  );
}

const CHART_TYPES = [
  { key: 'bar', label: 'Bar' },
  { key: 'line', label: 'Line' },
  { key: 'area', label: 'Area' },
];

const METRICS = {
  carts:  { label: 'Carts',         a: 'total',    b: 'converted',        aName: 'Abandoned', bName: 'Recovered',        format: (n) => Number(n).toLocaleString() },
  amount: { label: 'Amount',        a: 'amount',   b: 'recovered_amount', aName: 'Total',     bName: 'Recovered',        format: (n) => Number(n || 0).toLocaleString(undefined, { maximumFractionDigits: 0 }) },
  rate:   { label: 'Recovery Rate', single: true,  compute: (r) => (Number(r.total) > 0 ? (Number(r.converted) / Number(r.total)) * 100 : 0), aName: 'Recovery %', format: (n) => `${Number(n).toFixed(1)}%` },
};

function niceTicks(max, count = 4) {
  if (max <= 0) return [0];
  const step = max / count;
  return Array.from({ length: count + 1 }, (_, i) => Math.round(step * i));
}

function TrendChart({ trend, loading, chartType, metric }) {
  const items = Array.isArray(trend) ? trend : [];
  const cfg = METRICS[metric] || METRICS.carts;

  // Extract series values
  const seriesA = items.map((r) => (cfg.compute ? cfg.compute(r) : Number(r[cfg.a]) || 0));
  const seriesB = cfg.single ? null : items.map((r) => Number(r[cfg.b]) || 0);
  const max = Math.max(
    1,
    ...seriesA,
    ...(seriesB || []),
  );

  // Colors
  const colorA = '#818cf8';   // indigo
  const colorAStop = '#c7d2fe';
  const colorB = '#7c3aed';   // violet
  const colorBStop = '#a78bfa';

  const W = 720; // internal SVG width; scaled by viewBox
  const H = 200;
  const PAD_L = 40, PAD_R = 12, PAD_T = 12, PAD_B = 26;
  const chartW = W - PAD_L - PAD_R;
  const chartH = H - PAD_T - PAD_B;
  const n = items.length;
  const stepX = n > 1 ? chartW / (n - 1) : chartW;
  const xAt = (i) => PAD_L + (n > 1 ? stepX * i : chartW / 2);
  const yAt = (v) => PAD_T + chartH - (v / max) * chartH;

  const ticks = niceTicks(max, 4);

  const pathFor = (values) => {
    if (!values.length) return '';
    return values.map((v, i) => `${i === 0 ? 'M' : 'L'} ${xAt(i)} ${yAt(v)}`).join(' ');
  };
  const areaFor = (values) => {
    if (!values.length) return '';
    const line = pathFor(values);
    const y0 = PAD_T + chartH;
    return `${line} L ${xAt(values.length - 1)} ${y0} L ${xAt(0)} ${y0} Z`;
  };

  // X-axis labels: show first, middle, last (or all if <=7)
  const labelIndices = n <= 7 ? items.map((_, i) => i) : [0, Math.floor((n - 1) / 2), n - 1];

  const renderBars = () => {
    const barGroupW = Math.max(6, Math.min(24, (stepX || chartW) * 0.7));
    const barW = cfg.single ? barGroupW : barGroupW / 2 - 1;
    return items.map((row, i) => {
      const aV = seriesA[i];
      const bV = seriesB ? seriesB[i] : null;
      const cx = xAt(i);
      if (cfg.single) {
        const h = Math.max(1, ((aV / max) * chartH) || 0);
        return (
          <g key={i}>
            <title>{`${row.day} — ${cfg.aName}: ${cfg.format(aV)}`}</title>
            <rect x={cx - barW / 2} y={PAD_T + chartH - h} width={barW} height={h} fill={colorB} rx="2" />
          </g>
        );
      }
      const aH = Math.max(1, ((aV / max) * chartH) || 0);
      const bH = Math.max(1, ((bV / max) * chartH) || 0);
      return (
        <g key={i}>
          <title>{`${row.day} — ${cfg.aName}: ${cfg.format(aV)}, ${cfg.bName}: ${cfg.format(bV)}`}</title>
          <rect x={cx - barW - 1} y={PAD_T + chartH - aH} width={barW} height={aH} fill={colorA} rx="2" />
          <rect x={cx + 1} y={PAD_T + chartH - bH} width={barW} height={bH} fill={colorB} rx="2" />
        </g>
      );
    });
  };

  return (
    <LegacyCard title="Daily Trend">
      <LegacyCard.Section>
        {loading ? (
          <Box padding="800">
            <InlineStack align="center">
              <Spinner accessibilityLabel="Loading trend" size="small" />
            </InlineStack>
          </Box>
        ) : items.length === 0 ? (
          <Text tone="subdued" as="p">No data in the selected range.</Text>
        ) : (
          <BlockStack gap="400">
            <svg viewBox={`0 0 ${W} ${H}`} width="100%" height={H} preserveAspectRatio="xMidYMid meet" role="img" aria-label="Daily trend chart">
              <defs>
                <linearGradient id="gradA" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor={colorAStop} stopOpacity="0.7" />
                  <stop offset="100%" stopColor={colorA} stopOpacity="0.05" />
                </linearGradient>
                <linearGradient id="gradB" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="0%" stopColor={colorBStop} stopOpacity="0.8" />
                  <stop offset="100%" stopColor={colorB} stopOpacity="0.05" />
                </linearGradient>
              </defs>

              {/* grid lines + y-ticks */}
              {ticks.map((t) => (
                <g key={t}>
                  <line x1={PAD_L} x2={W - PAD_R} y1={yAt(t)} y2={yAt(t)} stroke="#e5e7eb" strokeDasharray="3,3" />
                  <text x={PAD_L - 6} y={yAt(t) + 4} textAnchor="end" fontSize="10" fill="#94a3b8">{cfg.format(t)}</text>
                </g>
              ))}

              {/* series */}
              {chartType === 'bar' && renderBars()}

              {chartType === 'area' && (
                <>
                  {!cfg.single && <path d={areaFor(seriesA)} fill="url(#gradA)" />}
                  <path d={areaFor(cfg.single ? seriesA : seriesB)} fill="url(#gradB)" />
                  {!cfg.single && <path d={pathFor(seriesA)} stroke={colorA} strokeWidth="2" fill="none" />}
                  <path d={pathFor(cfg.single ? seriesA : seriesB)} stroke={colorB} strokeWidth="2" fill="none" />
                </>
              )}

              {chartType === 'line' && (
                <>
                  {!cfg.single && (
                    <>
                      <path d={pathFor(seriesA)} stroke={colorA} strokeWidth="2" fill="none" />
                      {seriesA.map((v, i) => <circle key={`a-${i}`} cx={xAt(i)} cy={yAt(v)} r="2.5" fill={colorA} />)}
                    </>
                  )}
                  <path d={pathFor(cfg.single ? seriesA : seriesB)} stroke={colorB} strokeWidth="2" fill="none" />
                  {(cfg.single ? seriesA : seriesB).map((v, i) => (
                    <circle key={`b-${i}`} cx={xAt(i)} cy={yAt(v)} r="2.5" fill={colorB} />
                  ))}
                </>
              )}

              {/* x labels */}
              {labelIndices.map((i) => (
                <text key={i} x={xAt(i)} y={H - 8} textAnchor="middle" fontSize="10" fill="#64748b">
                  {String(items[i].day).slice(5)}
                </text>
              ))}
            </svg>

            <InlineStack gap="400">
              {!cfg.single && (
                <InlineStack gap="150" blockAlign="center">
                  <span style={{ width: 12, height: 12, background: colorA, borderRadius: 3 }} />
                  <Text variant="bodySm" as="span">{cfg.aName}</Text>
                </InlineStack>
              )}
              <InlineStack gap="150" blockAlign="center">
                <span style={{ width: 12, height: 12, background: colorB, borderRadius: 3 }} />
                <Text variant="bodySm" as="span">{cfg.single ? cfg.aName : cfg.bName}</Text>
              </InlineStack>
            </InlineStack>
          </BlockStack>
        )}
      </LegacyCard.Section>
    </LegacyCard>
  );
}

function PlatformBreakdown({ rows, loading }) {
  const list = Array.isArray(rows) ? rows : [];
  const totalAll = list.reduce((s, r) => s + (Number(r.total) || 0), 0) || 1;

  return (
    <LegacyCard title="By Platform">
      <LegacyCard.Section>
        {loading ? (
          <Box padding="800">
            <InlineStack align="center">
              <Spinner accessibilityLabel="Loading breakdown" size="small" />
            </InlineStack>
          </Box>
        ) : list.length === 0 ? (
          <Text tone="subdued" as="p">No platform data.</Text>
        ) : (
          <BlockStack gap="300">
            {list.map((row) => {
              const pct = Math.round(((Number(row.total) || 0) / totalAll) * 100);
              return (
                <BlockStack key={row.platformType} gap="100">
                  <InlineStack align="space-between">
                    <Text variant="bodyMd" fontWeight="semibold" as="span">
                      {row.platformType || 'Unknown'}
                    </Text>
                    <InlineStack gap="200" blockAlign="center">
                      <Text variant="bodySm" tone="subdued" as="span">{Number(row.total).toLocaleString()} carts</Text>
                      <Badge tone="magic">{Number(row.converted).toLocaleString()} recovered</Badge>
                    </InlineStack>
                  </InlineStack>
                  <ProgressBar progress={pct} size="small" />
                </BlockStack>
              );
            })}
          </BlockStack>
        )}
      </LegacyCard.Section>
    </LegacyCard>
  );
}

export default function AbandonedCartAnalytics() {
  const navigate = useNavigate();

  const [dateRange, setDateRange] = useState('all');
  const [startDate, setStartDate] = useState('');
  const [endDate, setEndDate] = useState('');
  const [platformType, setPlatformType] = useState([]);
  const [cartStatus, setCartStatus] = useState('');

  const [datePopoverActive, setDatePopoverActive] = useState(false);
  const [platformPopoverActive, setPlatformPopoverActive] = useState(false);
  const [statusPopoverActive, setStatusPopoverActive] = useState(false);

  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [chartType, setChartType] = useState('bar');
  const [chartMetric, setChartMetric] = useState('carts');
  const feedback = useApiFeedback();

  const load = useCallback(async () => {
    try {
      setLoading(true);
      feedback.clear();
      const effectiveDateRange = (startDate && endDate) ? '' : dateRange;
      const res = await fetchAbandonedAnalyticsSummary({
        startDate,
        endDate,
        dateRange: effectiveDateRange,
        platformType,
        cartStatus,
      });
      setData(res?.data ?? null);
    } catch (e) {
      setData(null);
      feedback.showError(e);
    } finally {
      setLoading(false);
    }
  // feedback methods are stable; excluded intentionally to avoid re-fetch loops
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [startDate, endDate, dateRange, platformType, cartStatus]);

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

  const dateLabel = useMemo(() => {
    if (startDate && endDate) return `${startDate} → ${endDate}`;
    const preset = DATE_PRESETS.find((p) => p.value === dateRange);
    return preset ? preset.label : 'All time';
  }, [startDate, endDate, dateRange]);

  const platformLabel = useMemo(() => {
    if (!platformType.length) return 'All platforms';
    if (platformType.length === 1) {
      return PLATFORMS.find((p) => p.value === platformType[0])?.label || platformType[0];
    }
    return `${platformType.length} platforms`;
  }, [platformType]);

  const statusLabel = useMemo(() => {
    if (cartStatus === '' || cartStatus == null) return 'All statuses';
    return STATUS_OPTIONS.find((s) => s.value === String(cartStatus))?.label || 'All statuses';
  }, [cartStatus]);

  const clearAll = () => {
    setDateRange('all');
    setStartDate('');
    setEndDate('');
    setPlatformType([]);
    setCartStatus('');
  };

  const total = Number(data?.total) || 0;
  const amount = Number(data?.amount) || 0;
  const converted = Number(data?.converted) || 0;
  const conversionRate = Number(data?.conversionRate) || 0;
  const recoveredAmount = Number(data?.recoveredAmount) || 0;
  const amountRecoveryRate = Number(data?.amountRecoveryRate) || 0;
  const fmtMoney = (n) => Number(n || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const currencyFmt = fmtMoney(amount);
  const recoveredFmt = fmtMoney(recoveredAmount);

  return (
    <Page
      title="Abandoned Cart Analytics"
      subtitle="Track total abandoned carts, revenue at risk, and recoveries"
      fullWidth
      backAction={{ content: 'Lists', onAction: () => navigate('/app/lists') }}
      primaryAction={{
        content: 'Refresh',
        icon: RefreshIcon,
        onAction: load,
        loading,
      }}
      secondaryActions={[
        {
          content: 'View Cart List',
          onAction: () => navigate('/app/abandoned-cart-list'),
        },
      ]}
    >
      <BlockStack gap="400">
        {feedback.banner}

        {/* Filter bar */}
        <LegacyCard>
          <LegacyCard.Section>
            <InlineStack gap="300" align="start" blockAlign="center" wrap>
              <InlineStack gap="100" blockAlign="center">
                <Icon source={FilterIcon} tone="subdued" />
                <Text variant="bodyMd" fontWeight="semibold" as="span">Filters:</Text>
              </InlineStack>

              <Popover
                active={datePopoverActive}
                activator={
                  <Button onClick={() => setDatePopoverActive((v) => !v)} disclosure>
                    {dateLabel}
                  </Button>
                }
                onClose={() => setDatePopoverActive(false)}
              >
                <Box padding="400" minWidth="260px">
                  <BlockStack gap="300">
                    <ActionList
                      items={DATE_PRESETS.map((p) => ({
                        content: p.label,
                        active: dateRange === p.value && !startDate && !endDate,
                        onAction: () => {
                          setDateRange(p.value);
                          setStartDate('');
                          setEndDate('');
                          setDatePopoverActive(false);
                        },
                      }))}
                    />
                    <Divider />
                    <Text variant="bodySm" tone="subdued" as="p">Or pick a custom range</Text>
                    <TextField label="Start date" type="date" value={startDate} onChange={setStartDate} autoComplete="off" />
                    <TextField label="End date" type="date" value={endDate} onChange={setEndDate} autoComplete="off" />
                    <InlineStack align="end">
                      <Button onClick={() => setDatePopoverActive(false)} variant="primary" disabled={!(startDate && endDate)}>Apply</Button>
                    </InlineStack>
                  </BlockStack>
                </Box>
              </Popover>

              <Popover
                active={platformPopoverActive}
                activator={
                  <Button onClick={() => setPlatformPopoverActive((v) => !v)} disclosure>
                    {platformLabel}
                  </Button>
                }
                onClose={() => setPlatformPopoverActive(false)}
              >
                <Box padding="400" minWidth="240px">
                  <ChoiceList
                    allowMultiple
                    title="Platforms"
                    titleHidden
                    choices={PLATFORMS}
                    selected={platformType}
                    onChange={setPlatformType}
                  />
                </Box>
              </Popover>

              <Popover
                active={statusPopoverActive}
                activator={
                  <Button onClick={() => setStatusPopoverActive((v) => !v)} disclosure>
                    {statusLabel}
                  </Button>
                }
                onClose={() => setStatusPopoverActive(false)}
              >
                <Box padding="400" minWidth="220px">
                  <ChoiceList
                    title="Status"
                    titleHidden
                    choices={[{ label: 'All statuses', value: '' }, ...STATUS_OPTIONS]}
                    selected={[cartStatus]}
                    onChange={(v) => { setCartStatus(v[0] ?? ''); setStatusPopoverActive(false); }}
                  />
                </Box>
              </Popover>

              <Button onClick={clearAll} icon={XIcon} variant="plain">Clear</Button>
            </InlineStack>
          </LegacyCard.Section>
        </LegacyCard>

        {/* KPI cards */}
        <InlineGrid columns={{ xs: 1, sm: 2, md: 4 }} gap="400">
          <StatCard
            title="Total Abandoned Carts"
            value={total.toLocaleString()}
            subtitle="All carts in selected range"
            icon={CartIcon}
            accent={{
              bg: 'linear-gradient(135deg,#eef2ff 0%,#ffffff 100%)',
              border: '#e0e7ff',
              iconBg: '#eef2ff',
              iconColor: '#4f46e5',
              iconTone: 'info',
            }}
            loading={loading}
          />
          <StatCard
            title="Total Amount"
            value={currencyFmt}
            subtitle="Value at risk (sum of cart totals)"
            icon={CashDollarIcon}
            accent={{
              bg: 'linear-gradient(135deg,#ecfeff 0%,#ffffff 100%)',
              border: '#cffafe',
              iconBg: '#ecfeff',
              iconColor: '#0891b2',
              iconTone: 'info',
            }}
            loading={loading}
          />
          <StatCard
            title="Converted (Recovered)"
            value={converted.toLocaleString()}
            subtitle={`${conversionRate}% of carts recovered`}
            icon={ChartVerticalIcon}
            accent={{
              bg: 'linear-gradient(135deg,#f5f3ff 0%,#ffffff 100%)',
              border: '#ede9fe',
              iconBg: '#f5f3ff',
              iconColor: '#7c3aed',
              iconTone: 'magic',
            }}
            loading={loading}
          />
          <StatCard
            title="Recovered Amount"
            value={recoveredFmt}
            subtitle={`${amountRecoveryRate}% of value recovered`}
            icon={CashDollarIcon}
            accent={{
              bg: 'linear-gradient(135deg,#ecfdf5 0%,#ffffff 100%)',
              border: '#d1fae5',
              iconBg: '#ecfdf5',
              iconColor: '#059669',
              iconTone: 'success',
            }}
            loading={loading}
          />
        </InlineGrid>

        {/* Chart mode toggles */}
        <LegacyCard>
          <LegacyCard.Section>
            <InlineStack align="space-between" blockAlign="center" wrap gap="300">
              <InlineStack gap="200" blockAlign="center">
                <Text variant="bodyMd" fontWeight="semibold" as="span">Metric:</Text>
                <ButtonGroup segmented>
                  {Object.entries(METRICS).map(([key, m]) => (
                    <Button key={key} pressed={chartMetric === key} onClick={() => setChartMetric(key)}>{m.label}</Button>
                  ))}
                </ButtonGroup>
              </InlineStack>
              <InlineStack gap="200" blockAlign="center">
                <Text variant="bodyMd" fontWeight="semibold" as="span">Chart:</Text>
                <ButtonGroup segmented>
                  {CHART_TYPES.map((t) => (
                    <Button key={t.key} pressed={chartType === t.key} onClick={() => setChartType(t.key)}>{t.label}</Button>
                  ))}
                </ButtonGroup>
              </InlineStack>
            </InlineStack>
          </LegacyCard.Section>
        </LegacyCard>

        {/* Trend + Platform breakdown */}
        <InlineGrid columns={{ xs: '1fr', md: '2fr 1fr' }} gap="400">
          <TrendChart trend={data?.trend} loading={loading} chartType={chartType} metric={chartMetric} />
          <PlatformBreakdown rows={data?.byPlatform} loading={loading} />
        </InlineGrid>
      </BlockStack>
    </Page>
  );
}
