import '../../../components/analytics/analytics.css';
import {
  ANALYTICS_GLOBAL_READ_PERMISSIONS,
  ANALYTICS_OPERATIONAL_READ_PERMISSIONS,
} from '@navi/config';
import type { AnalyticsOverviewDto } from '@navi/types';
import { formatDate, formatMoney, formatNumber } from '@navi/ui';
import Link from 'next/link';
import {
  EmptyState,
  PageHeader,
  StatusBadge,
} from '../../../components/DashboardPrimitives';
import {
  AnalyticsErrorState,
  AnalyticsForbiddenState,
  AnalyticsPanel,
} from '../../../components/analytics/AnalyticsStates';
import { AnalyticsFilterBar } from '../../../components/analytics/AnalyticsFilterBar';
import { KpiCard } from '../../../components/analytics/KpiCard';
import { ProviderHealthTable } from '../../../components/analytics/ProviderHealthTable';
import { RiskPanel } from '../../../components/analytics/RiskPanel';
import { BookingStatusChart } from '../../../components/analytics/charts/BookingStatusChart';
import { CustomerBehaviorFunnel } from '../../../components/analytics/charts/CustomerBehaviorFunnel';
import { ProviderReadinessChart } from '../../../components/analytics/charts/ProviderReadinessChart';
import { RevenueTrendChart } from '../../../components/analytics/charts/RevenueTrendChart';
import type { AnalyticsResult } from '../../../lib/analyticsApi';
import {
  fetchAnalyticsBookings,
  fetchAnalyticsCustomerBehavior,
  fetchAnalyticsOverview,
  fetchAnalyticsProviders,
  fetchAnalyticsRevenue,
} from '../../../lib/analyticsApi';
import { getCurrentAccess } from '../../../lib/permissions';

const DEFAULT_RANGE_DAYS = 30;

interface OverviewSearchParams {
  from?: string;
  to?: string;
  env?: 'DEMO' | 'SANDBOX' | 'PRODUCTION' | string;
}

export default async function Overview({
  searchParams,
}: {
  searchParams?: OverviewSearchParams;
}) {
  const access = await getCurrentAccess();
  if (!access) {
    return (
      <>
        <PageHeader title="Overview" eyebrow="Navi control center" />
        <EmptyState
          title="Sign in to view the overview"
          body="The dashboard requires an authenticated session with analytics permissions."
        />
      </>
    );
  }

  const permissions = access.permissions ?? [];
  const isSuperAdmin = permissions.includes('*');
  const canSeeGlobal =
    isSuperAdmin || ANALYTICS_GLOBAL_READ_PERMISSIONS.some((permission) => permissions.includes(permission));
  const canSeeProviders =
    isSuperAdmin ||
    ANALYTICS_OPERATIONAL_READ_PERMISSIONS.some((permission) => permissions.includes(permission));

  if (!canSeeGlobal && !canSeeProviders) {
    return (
      <>
        <PageHeader title="Overview" eyebrow="Navi control center" />
        <AnalyticsForbiddenState
          title="No analytics permissions"
          body="Your role does not include any analytics permissions. Ask an administrator if you need access."
        />
      </>
    );
  }

  const range = resolveRange(searchParams);
  const env =
    searchParams?.env === 'DEMO' || searchParams?.env === 'SANDBOX' || searchParams?.env === 'PRODUCTION'
      ? searchParams.env
      : undefined;

  const [overview, bookings, revenue, providers, customerBehavior] = await Promise.all([
    canSeeGlobal ? fetchAnalyticsOverview(range) : skipped<typeof fetchAnalyticsOverview>(),
    canSeeGlobal ? fetchAnalyticsBookings(range) : skipped<typeof fetchAnalyticsBookings>(),
    canSeeGlobal ? fetchAnalyticsRevenue(range) : skipped<typeof fetchAnalyticsRevenue>(),
    canSeeProviders
      ? fetchAnalyticsProviders(env ? { environment: env } : {})
      : skipped<typeof fetchAnalyticsProviders>(),
    canSeeGlobal
      ? fetchAnalyticsCustomerBehavior(range)
      : skipped<typeof fetchAnalyticsCustomerBehavior>(),
  ]);

  const overviewDto = overview.status === 'ok' ? overview.data : null;
  const bookingsDto = bookings.status === 'ok' ? bookings.data : null;
  const revenueDto = revenue.status === 'ok' ? revenue.data : null;
  const providersDto = providers.status === 'ok' ? providers.data : null;
  const behaviorDto = customerBehavior.status === 'ok' ? customerBehavior.data : null;

  return (
    <div className="stack">
      <PageHeader
        title="Overview"
        eyebrow={`Scope: ${overviewDto?.scope ?? (canSeeGlobal ? 'global' : 'limited')}`}
        description="A live operating snapshot for customer activity, partner readiness, finance signals, and operational risk."
      >
        {overviewDto ? (
          <span className="muted">
            Updated {formatDate(overviewDto.generatedAt, 'en', { dateStyle: 'medium', timeStyle: 'short' })}
          </span>
        ) : null}
      </PageHeader>

      <AnalyticsFilterBar
        defaultFrom={range.from}
        defaultTo={range.to}
        defaultEnvironment={env ?? ''}
      />

      <RiskPanel overview={overviewDto} revenue={revenueDto} providers={providersDto} />

      {canSeeGlobal ? (
        <>
          {renderKpiSection(overview)}
          <div className="two-col">
            <AnalyticsPanel
              title="Revenue trend"
              description={
                revenueDto
                  ? `Captured payments — ${revenueDto.currencyCode} totals per day.`
                  : 'Captured vs total payment intents per day.'
              }
            >
              {renderState(revenue, () =>
                revenueDto ? (
                  <RevenueTrendChart
                    series={revenueDto.paymentTotalsByDay}
                    currencyCode={revenueDto.currencyCode}
                  />
                ) : null,
              )}
            </AnalyticsPanel>
            <AnalyticsPanel
              title="Bookings by status"
              description="Where bookings are sitting in the lifecycle for the selected window."
            >
              {renderState(bookings, () =>
                bookingsDto ? <BookingStatusChart data={bookingsDto.byStatus} /> : null,
              )}
            </AnalyticsPanel>
          </div>

          <div className="two-col">
            <AnalyticsPanel
              title="Provider readiness"
              description="Distribution of category operating modes across the platform."
            >
              {renderState(providers, () =>
                providersDto ? <ProviderReadinessChart data={providersDto.byMode} /> : null,
              )}
            </AnalyticsPanel>
            <AnalyticsPanel
              title="Customer behavior funnel"
              description={
                behaviorDto
                  ? `Conversion rate ${(behaviorDto.conversionRate * 100).toFixed(2)}% (booking attempts ÷ searches + listing views).`
                  : 'Searches → views → saves → booking attempts.'
              }
            >
              {renderState(customerBehavior, () =>
                behaviorDto ? (
                  <CustomerBehaviorFunnel
                    searches={behaviorDto.searches.total}
                    listingViews={behaviorDto.listingViews}
                    saves={behaviorDto.saves}
                    bookingAttempts={behaviorDto.bookingAttempts}
                  />
                ) : null,
              )}
            </AnalyticsPanel>
          </div>

          <AnalyticsPanel
            title="Recent bookings"
            description="The newest reservations across the platform for the selected window."
            actions={
              <Link className="btn-secondary" href="/bookings">
                View all bookings
              </Link>
            }
          >
            {renderState(bookings, () =>
              bookingsDto && bookingsDto.recent.length ? (
                <div className="table-wrap">
                  <table className="table">
                    <thead>
                      <tr>
                        <th>ID</th>
                        <th>Kind</th>
                        <th>Status</th>
                        <th>Total</th>
                        <th>Created</th>
                      </tr>
                    </thead>
                    <tbody>
                      {bookingsDto.recent.map((booking) => (
                        <tr key={booking.id}>
                          <td className="mono">{booking.id}</td>
                          <td>{booking.kind}</td>
                          <td>
                            <StatusBadge value={booking.status} />
                          </td>
                          <td>{formatMoney(booking.total, 'en')}</td>
                          <td>
                            {formatDate(booking.createdAt, 'en', {
                              dateStyle: 'medium',
                              timeStyle: 'short',
                            })}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              ) : (
                <EmptyState
                  title="No bookings in this window"
                  body="When customers book, the most recent reservations will appear here."
                />
              ),
            )}
          </AnalyticsPanel>
        </>
      ) : null}

      <AnalyticsPanel
        title="Provider health"
        description="Integrations reporting DOWN, DEGRADED, or with a recent error message."
        actions={
          <Link className="btn-secondary" href="/provider-health">
            Open provider health
          </Link>
        }
      >
        {renderState(providers, () => <ProviderHealthTable providers={providersDto} />)}
      </AnalyticsPanel>
    </div>
  );
}

function renderKpiSection(result: AnalyticsResult<AnalyticsOverviewDto>) {
  if (result.status === 'forbidden') {
    return (
      <AnalyticsForbiddenState
        title="KPI cards hidden"
        body="Your role does not include analytics read permissions for global KPIs."
      />
    );
  }
  if (result.status === 'error') {
    return <AnalyticsErrorState title="Could not load KPIs" body={result.message} />;
  }
  const metrics = result.data.metrics;
  return (
    <div className="kpi-grid">
      <KpiCard label="Active users" value={formatNumber(metrics.activeUsers)} />
      <KpiCard label="Bookings this week" value={formatNumber(metrics.bookingsThisWeek)} />
      <KpiCard label="Published listings" value={formatNumber(metrics.publishedListings)} />
      <KpiCard
        label="Pending partner reviews"
        value={formatNumber(metrics.pendingPartnerReviews)}
        tone={metrics.pendingPartnerReviews > 0 ? 'warning' : 'neutral'}
      />
      <KpiCard label="Payment intents" value={formatNumber(metrics.paymentIntentCount)} />
      <KpiCard label="Payment volume" value={formatMoney(metrics.paymentIntentTotal, 'en')} />
      <KpiCard
        label="Refunds requested"
        value={formatNumber(metrics.requestedRefundCount)}
        tone={metrics.requestedRefundCount > 0 ? 'warning' : 'neutral'}
      />
      <KpiCard
        label="Live providers"
        value={formatNumber(metrics.liveProviderCount)}
        tone={metrics.liveProviderCount > 0 ? 'positive' : 'neutral'}
      />
      <KpiCard
        label="Provider errors"
        value={formatNumber(metrics.providerErrorCount)}
        tone={metrics.providerErrorCount > 0 ? 'critical' : 'positive'}
      />
    </div>
  );
}

function renderState<T>(result: AnalyticsResult<T>, render: () => React.ReactNode) {
  if (result.status === 'forbidden') {
    return <AnalyticsForbiddenState />;
  }
  if (result.status === 'error') {
    return <AnalyticsErrorState title="Could not load data" body={result.message} />;
  }
  return render();
}

function resolveRange(params?: OverviewSearchParams) {
  const now = new Date();
  const to = params?.to ? new Date(params.to) : now;
  const from = params?.from
    ? new Date(params.from)
    : new Date(to.getTime() - DEFAULT_RANGE_DAYS * 24 * 60 * 60 * 1000);
  return {
    from: from.toISOString(),
    to: to.toISOString(),
    granularity: 'day' as const,
  };
}

async function skipped<TFunc extends (...args: never[]) => Promise<AnalyticsResult<unknown>>>(): Promise<
  Awaited<ReturnType<TFunc>>
> {
  return { status: 'forbidden' } as Awaited<ReturnType<TFunc>>;
}
