'use client';
import { ErrorState } from '@/components/ui/feedback/ErrorState';

import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { HydratedIsland } from '@/components/HydratedIsland';
import { useT, useLocale } from '@/lib/i18n/react';
import { formatInteger } from '@/lib/format';
import { Button } from '@/components/ui/primitives/Button';
import { Table } from '@/components/ui/primitives/Table/Table';
import { Tabs } from '@/components/ui/layout/Tabs/Tabs';
import { AdminTimeSeriesChart } from '@/components/ui/domain/admin/AdminTimeSeriesChart/AdminTimeSeriesChart';
import { PageShellSkeleton } from '@/components/ui/feedback/Skeleton';
import { ShareKpiStrip } from './ShareKpiStrip';
import { ShareLinksTable } from './ShareLinksTable';
import { AudienceTab } from './AudienceTab';
import { ConversionsTab } from './ConversionsTab';
import type { ShareConversionsResult } from '@/server/admin/resources/sharing/conversions.js';
import type { ShareTimeseriesResult } from '@/server/admin/resources/sharing/timeseries.js';
import { QueryBoundary } from '@platform-modules/ui-primitives';

type StatsData = {
  kpis: {
    totalClicks: number;
    uniqueDealsShared: number;
    totalLinks: number;
    avgClicksPerLink: number;
    totalClicksSuspicious: number;
  };
  channelBreakdown: Array<{ channel: string; clicks: number; links: number }>;
  topDeals: Array<{ dealId: string; dealTitle: string; totalClicks: number; totalLinks: number }>;
  deviceBreakdown: { mobile: number; desktop: number; bot: number; other: number };
  countryBreakdown: Array<{ country: string; clicks: number }>;
};

async function fetchStats(from: string, to: string): Promise<StatsData> {
  const res = await fetch(`/api/admin/share/stats?from=${from}&to=${to}`);
  if (!res.ok) throw new Error('fetch failed');
  const json = (await res.json()) as { data: StatsData };
  return json.data;
}

async function fetchConversions(from: string, to: string): Promise<ShareConversionsResult> {
  const res = await fetch(`/api/admin/share/conversions?from=${from}&to=${to}`);
  if (!res.ok) throw new Error('Failed to fetch conversions');
  return ((await res.json()) as { data: ShareConversionsResult }).data;
}

async function fetchTimeseries(
  from: string,
  to: string,
  bucket: 'd' | 'w' | 'm',
): Promise<ShareTimeseriesResult> {
  const res = await fetch(`/api/admin/share/timeseries?from=${from}&to=${to}&bucket=${bucket}`);
  if (!res.ok) throw new Error('Failed to fetch timeseries');
  return ((await res.json()) as { data: ShareTimeseriesResult }).data;
}

function daysAgo(n: number): string {
  const d = new Date();
  d.setDate(d.getDate() - n);
  return d.toISOString().slice(0, 10);
}

export function ShareDashboard() {
  return (
    <HydratedIsland>
      <ShareDashboardInner />
    </HydratedIsland>
  );
}

function ShareDashboardInner() {
  const t = useT('admin_sharing');
  const tCommon = useT('common');
  const { locale } = useLocale();
  const [range, setRange] = useState<'7d' | '30d' | '90d'>('30d');
  const rangeMap = { '7d': 7, '30d': 30, '90d': 90 };
  const bucketMap: Record<'7d' | '30d' | '90d', 'd' | 'w' | 'm'> = {
    '7d': 'd',
    '30d': 'w',
    '90d': 'm',
  };

  const from = daysAgo(rangeMap[range]);
  const to = new Date().toISOString().slice(0, 10);
  const bucket = bucketMap[range];

  const statsQuery = useQuery({
    queryKey: ['admin', 'share', 'stats', range],
    queryFn: () => fetchStats(from, to),
    staleTime: 60_000,
  });

  const { data: conversionsData } = useQuery({
    queryKey: ['admin', 'share', 'conversions', range],
    queryFn: () => fetchConversions(from, to),
    staleTime: 60_000,
  });

  const { data: timeseriesData, isLoading: timeseriesLoading } = useQuery({
    queryKey: ['admin', 'share', 'timeseries', range],
    queryFn: () => fetchTimeseries(from, to, bucket),
    staleTime: 60_000,
  });

  return (
    <QueryBoundary
      query={statsQuery}
      skeleton={<PageShellSkeleton />}
      errorFallback={(retry) => (
        <ErrorState
          title={tCommon('error_loading')}
          action={
            <Button variant="secondary" size="sm" onClick={() => retry()}>
              {tCommon('retry')}
            </Button>
          }
        />
      )}
    >
      {(statsData) => {
        const topChannel = statsData.channelBreakdown[0]?.channel ?? null;
        const suspiciousRate =
          statsData.kpis.totalClicks > 0
            ? (statsData.kpis.totalClicksSuspicious / statsData.kpis.totalClicks) * 100
            : 0;

        const overviewPanel = (
          <div className="mt-4 grid gap-6 md:grid-cols-2">
            <div className="rounded-lg border p-4">
              <h2 className="mb-3 font-medium">{t('channel_breakdown_title')}</h2>
              <ul className="space-y-2">
                {statsData.channelBreakdown.map((c) => (
                  <li key={c.channel} className="flex justify-between text-sm">
                    <span>{t(`channel_${c.channel}` as never)}</span>
                    <span className="font-medium tabular-nums">
                      {formatInteger(c.clicks, locale)}
                    </span>
                  </li>
                ))}
              </ul>
            </div>
          </div>
        );

        const dealsPanel = (
          <div className="mt-4 rounded-lg border p-4">
            <h2 className="mb-3 font-medium">{t('top_deals')}</h2>
            <Table>
              <Table.Head>
                <Table.Row>
                  <Table.HeadCell>{t('col_deal')}</Table.HeadCell>
                  <Table.HeadCell className="text-end">{t('col_links')}</Table.HeadCell>
                  <Table.HeadCell className="text-end">{t('clicks_col')}</Table.HeadCell>
                </Table.Row>
              </Table.Head>
              <Table.Body>
                {statsData.topDeals.map((d) => (
                  <Table.Row key={d.dealId}>
                    <Table.Cell>{d.dealTitle}</Table.Cell>
                    <Table.Cell className="text-end tabular-nums">{d.totalLinks}</Table.Cell>
                    <Table.Cell className="text-end tabular-nums">{d.totalClicks}</Table.Cell>
                  </Table.Row>
                ))}
              </Table.Body>
            </Table>
          </div>
        );

        const linksPanel = (
          <div className="mt-4 rounded-lg border p-4">
            <ShareLinksTable />
          </div>
        );

        const audiencePanel = (
          <AudienceTab
            deviceBreakdown={statsData.deviceBreakdown}
            countryBreakdown={statsData.countryBreakdown}
          />
        );

        const conversionsPanel = <ConversionsTab data={conversionsData} />;

        const clicksSeries = (timeseriesData?.series ?? []).map((p) => ({
          period: p.date,
          value: p.clicks,
        }));
        const linksSeries = (timeseriesData?.series ?? []).map((p) => ({
          period: p.date,
          value: p.links,
        }));

        const timeseriesPanel = (
          <div className="mt-4 grid gap-6 md:grid-cols-2">
            <div className="rounded-lg border p-4">
              <AdminTimeSeriesChart
                data={clicksSeries}
                title={t('timeseries_clicks_title')}
                format="count"
                loading={timeseriesLoading}
                bucketSize={bucket}
              />
            </div>
            <div className="rounded-lg border p-4">
              <AdminTimeSeriesChart
                data={linksSeries}
                title={t('timeseries_links_title')}
                format="count"
                loading={timeseriesLoading}
                bucketSize={bucket}
              />
            </div>
          </div>
        );

        return (
          <div className="space-y-6" dir="rtl">
            <div className="flex items-center justify-end">
              <div className="flex gap-2">
                {(['7d', '30d', '90d'] as const).map((r) => (
                  <Button
                    key={r}
                    variant={range === r ? 'primary' : 'ghost'}
                    size="sm"
                    onClick={() => setRange(r)}
                  >
                    {t(`date_range_${r}` as never)}
                  </Button>
                ))}
              </div>
            </div>

            <ShareKpiStrip
              totalClicks={statsData.kpis.totalClicks}
              uniqueDealsShared={statsData.kpis.uniqueDealsShared}
              totalLinks={statsData.kpis.totalLinks}
              topChannel={topChannel}
              avgClicksPerLink={statsData.kpis.avgClicksPerLink}
              suspiciousRate={suspiciousRate}
            />

            <Tabs
              defaultValue="links"
              items={[
                { value: 'overview', label: t('tab_overview') },
                { value: 'deals', label: t('tab_deals') },
                { value: 'links', label: t('tab_links') },
                { value: 'audience', label: t('tab_audience') },
                { value: 'conversions', label: t('tab_conversions') },
                { value: 'timeseries', label: t('tab_timeseries') },
              ]}
              panels={{
                overview: overviewPanel,
                deals: dealsPanel,
                links: linksPanel,
                audience: audiencePanel,
                conversions: conversionsPanel,
                timeseries: timeseriesPanel,
              }}
              mode="customer"
            />
          </div>
        );
      }}
    </QueryBoundary>
  );
}
