'use client';

import { useQuery } from '@tanstack/react-query';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Spinner } from '@/components/ui/spinners';
import {
  fetchAnalyticsOverview,
  fetchFunnel,
} from '@/network/apis/dashboard/marketing-analytics/marketing-analytics.apis';
import { FunnelStep } from '@/network/apis/dashboard/marketing-analytics/type';
import { dropOffClass, eventLabel, isConversion } from '../labels';

/**
 * Where creators and brands drop out of the journey.
 *
 * The bar is drawn relative to the first step rather than to the widest step,
 * so the shape of the funnel is the shape of the loss — a step that keeps 90%
 * looks nearly as wide as entry, and one that keeps 5% looks like the cliff it
 * is. Scaling each bar to its own maximum would flatten exactly the thing this
 * chart exists to show.
 */
function FunnelColumn({
  title,
  steps,
  accent,
}: {
  title: string;
  steps: FunnelStep[];
  accent: string;
}) {
  const entry = steps[0]?.users ?? 0;

  return (
    <Card>
      <CardHeader className="pb-3">
        <CardTitle className="text-base font-semibold">{title}</CardTitle>
      </CardHeader>
      <CardContent className="pt-0 space-y-3">
        {entry === 0 ? (
          <p className="text-sm text-muted-foreground py-6 text-center">
            Nobody entered this journey in the selected range.
          </p>
        ) : (
          steps.map((step, i) => {
            const previous = i === 0 ? step.users : steps[i - 1].users;
            // Loss against the step before, which is the actionable number:
            // "we lose them here", not "we lost them somewhere upstream".
            const dropOff =
              previous > 0 ? ((previous - step.users) / previous) * 100 : 0;
            const width = entry > 0 ? Math.max((step.users / entry) * 100, 1.5) : 0;

            return (
              <div key={step.event} className="space-y-1">
                <div className="flex items-baseline justify-between gap-3">
                  <span className="text-sm font-medium truncate flex items-center gap-1.5">
                    {eventLabel(step.event)}
                    {/* A conversion per the tracking plan — these are the
                        steps that define success, not just another row. */}
                    {isConversion(step.event) && (
                      <span
                        title="Conversion (Key Event)"
                        className="text-[10px] font-semibold px-1.5 py-0.5 rounded border border-emerald-200 bg-emerald-50 text-emerald-700 dark:border-emerald-800 dark:bg-emerald-950/30 dark:text-emerald-400"
                      >
                        KEY
                      </span>
                    )}
                  </span>
                  <span className="text-sm font-semibold tabular-nums shrink-0">
                    {step.users.toLocaleString()}
                    {step.conversion !== null && (
                      <span className="ml-2 text-xs font-normal text-muted-foreground">
                        {step.conversion}%
                      </span>
                    )}
                  </span>
                </div>
                <div className="h-2 rounded-full bg-muted overflow-hidden">
                  <div
                    className={`h-full rounded-full ${accent}`}
                    style={{ width: `${width}%` }}
                  />
                </div>
                {i > 0 && dropOff > 0 && (
                  <p className={`text-xs ${dropOffClass(dropOff)}`}>
                    {dropOff.toFixed(0)}% dropped off from the step above
                  </p>
                )}
              </div>
            );
          })
        )}
      </CardContent>
    </Card>
  );
}

export function FunnelBoard({ from, to }: { from: string; to: string }) {
  const overview = useQuery({
    queryKey: ['analytics', 'overview', from, to],
    queryFn: () => fetchAnalyticsOverview(from, to),
  });

  const funnel = useQuery({
    queryKey: ['analytics', 'funnel', from, to],
    queryFn: () => fetchFunnel(from, to),
  });

  const cards = [
    { label: 'Events recorded', value: overview.data?.total_events, color: 'text-blue-600' },
    { label: 'Active people', value: overview.data?.active_users, color: 'text-emerald-600' },
    { label: 'New creators', value: overview.data?.new_creators, color: 'text-violet-600' },
    { label: 'New brands', value: overview.data?.new_brands, color: 'text-amber-600' },
  ];

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-1 sm:grid-cols-4 gap-3">
        {cards.map((card) => (
          <Card key={card.label}>
            <CardContent className="p-4">
              <p className="text-xs font-medium text-muted-foreground">
                {card.label}
              </p>
              <p className={`text-xl font-bold mt-1 ${card.color}`}>
                {overview.isLoading ? (
                  <Spinner className="h-4 w-4" />
                ) : (
                  (card.value ?? 0).toLocaleString()
                )}
              </p>
            </CardContent>
          </Card>
        ))}
      </div>

      {funnel.isLoading ? (
        <div className="flex justify-center py-10">
          <Spinner className="h-6 w-6" />
        </div>
      ) : (
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
          <FunnelColumn
            title="Creator journey"
            steps={funnel.data?.creator ?? []}
            accent="bg-violet-500"
          />
          <FunnelColumn
            title="Brand journey"
            steps={funnel.data?.brand ?? []}
            accent="bg-blue-500"
          />
        </div>
      )}
    </div>
  );
}
