'use client';

import { useState, useEffect, useCallback } from 'react';
import {
  Users,
  DollarSign,
  Zap,
  TrendingUp,
  UserPlus,
  Activity,
  ArrowUpRight,
  ArrowDownRight,
  RefreshCw,
  Cpu,
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton';
import {
  mockSummaryStats,
  formatNumber,
  formatCurrency,
  type DailyMetric,
  type User,
  type ModelUsage,
} from '@/lib/mock-data';
import {
  apiGetDashboardStats,
  apiGetUsage,
  apiListUsers,
  apiGetRevenueAnalytics,
  type DashboardStats,
  type ApiUsageRecord,
  type RevenueAnalytics,
} from '@/lib/api';
import { PageHeader } from '@bytelyst/dashboard-components';
import { Reveal, StaggerList } from '@bytelyst/motion';
import { AreaChart, BarChart } from '@/components/charts';
import { seriesValues, dateBars } from '@/lib/chart-data';

function buildKpiCards(stats: typeof mockSummaryStats, revenue?: RevenueAnalytics | null) {
  const fmt = (n: number) => (n >= 0 ? `+${n}%` : `${n}%`);
  const mrrChange = revenue?.mrrChange ?? 0;
  const churnRate = revenue?.churnRate ?? stats.churnRate;

  return [
    {
      title: 'Total Users',
      value: stats.totalUsers.toString(),
      change: revenue
        ? fmt(
            Math.round(
              ((revenue.newSubscriptions - revenue.canceledSubscriptions) /
                (stats.totalUsers || 1)) *
                100 *
                10
            ) / 10
          )
        : '—',
      trend: (revenue
        ? revenue.newSubscriptions >= revenue.canceledSubscriptions
          ? 'up'
          : 'down'
        : 'up') as 'up' | 'down',
      icon: Users,
      subtitle: `${stats.activeUsers} active`,
    },
    {
      title: 'Monthly Revenue',
      value: formatCurrency(revenue?.mrr ?? stats.monthlyRecurring),
      change: revenue ? fmt(mrrChange) : '—',
      trend: (mrrChange >= 0 ? 'up' : 'down') as 'up' | 'down',
      icon: DollarSign,
      subtitle: `${formatCurrency(revenue?.totalRevenue ?? stats.totalRevenue)} total`,
    },
    {
      title: 'Tokens This Month',
      value: formatNumber(stats.totalTokensThisMonth),
      change: '—',
      trend: 'up' as const,
      icon: Zap,
      subtitle: `${formatNumber(stats.avgTokensPerUser)} avg/user`,
    },
    {
      title: 'New Users',
      value: (revenue?.newSubscriptions ?? stats.newUsersThisMonth).toString(),
      change: '—',
      trend: 'up' as const,
      icon: UserPlus,
      subtitle: `${stats.conversionRate}% conversion`,
    },
    {
      title: 'Requests This Month',
      value: formatNumber(stats.totalRequestsThisMonth),
      change: '—',
      trend: 'up' as const,
      icon: Activity,
      subtitle: 'API calls',
    },
    {
      title: 'Churn Rate',
      value: `${churnRate}%`,
      change: revenue ? `${revenue.churnCount} canceled` : '—',
      trend: (churnRate <= 5 ? 'down' : 'up') as 'up' | 'down',
      icon: TrendingUp,
      subtitle: 'Month over month',
    },
  ];
}

function mergeApiStats(
  base: typeof mockSummaryStats,
  api: DashboardStats
): typeof mockSummaryStats {
  const totalUsers = api.users.total || base.totalUsers;
  const totalTokens = api.usage.totalWords || base.totalTokensThisMonth;
  return {
    ...base,
    totalUsers,
    activeUsers: totalUsers,
    totalTokensThisMonth: totalTokens,
    totalRequestsThisMonth: api.usage.totalDictations || base.totalRequestsThisMonth,
    avgTokensPerUser: totalUsers > 0 ? Math.round(totalTokens / totalUsers) : 0,
  };
}

function usageRecordsToDailyMetrics(records: ApiUsageRecord[]): DailyMetric[] {
  const byDate = new Map<string, DailyMetric>();
  for (const r of records) {
    const existing = byDate.get(r.date);
    if (existing) {
      existing.totalTokens += r.tokensUsed;
      existing.totalRequests += r.dictations;
      existing.revenue += r.costUsd;
      existing.activeUsers += 1;
    } else {
      byDate.set(r.date, {
        date: r.date,
        activeUsers: 1,
        totalRequests: r.dictations,
        totalTokens: r.tokensUsed,
        revenue: r.costUsd,
      });
    }
  }
  return Array.from(byDate.values()).sort((a, b) => a.date.localeCompare(b.date));
}

function buildModelUsage(records: ApiUsageRecord[]): ModelUsage[] {
  // Aggregate per-model from real usage records (each record now has optional model field)
  const byModel: Record<string, { tokens: number; requests: number; cost: number }> = {};
  for (const r of records) {
    const model = (r as unknown as { model?: string }).model || 'gpt-4o-mini';
    if (!byModel[model]) byModel[model] = { tokens: 0, requests: 0, cost: 0 };
    byModel[model].tokens += r.tokensUsed;
    byModel[model].requests += r.dictations;
    byModel[model].cost += r.costUsd;
  }

  const totalTokens = Object.values(byModel).reduce((s, m) => s + m.tokens, 0);
  if (totalTokens === 0) return [];

  return Object.entries(byModel).map(([model, stats]) => ({
    model,
    tokens: stats.tokens,
    requests: stats.requests,
    cost: stats.cost,
    percentage: Math.round((stats.tokens / totalTokens) * 100),
  }));
}

function KpiSkeleton() {
  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between pb-2">
        <Skeleton className="h-4 w-24" />
        <Skeleton className="h-4 w-4 rounded" />
      </CardHeader>
      <CardContent>
        <Skeleton className="h-7 w-20 mb-2" />
        <Skeleton className="h-4 w-32" />
      </CardContent>
    </Card>
  );
}

function ChartSkeleton() {
  return (
    <Card>
      <CardHeader>
        <Skeleton className="h-5 w-48" />
      </CardHeader>
      <CardContent>
        <Skeleton className="h-[280px] w-full" />
      </CardContent>
    </Card>
  );
}

export default function DashboardPage() {
  const [stats, setStats] = useState({
    ...mockSummaryStats,
    totalUsers: 0,
    activeUsers: 0,
    totalRevenue: 0,
    monthlyRecurring: 0,
    totalTokensThisMonth: 0,
    totalRequestsThisMonth: 0,
    avgTokensPerUser: 0,
    newUsersThisMonth: 0,
    conversionRate: 0,
    churnRate: 0,
  });
  const [dailyMetrics, setDailyMetrics] = useState<DailyMetric[]>([]);
  const [recentUsers, setRecentUsers] = useState<User[]>([]);
  const [modelUsage, setModelUsage] = useState<ModelUsage[]>([]);
  const [revenue, setRevenue] = useState<RevenueAnalytics | null>(null);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [lastUpdated, setLastUpdated] = useState<Date | null>(null);

  const fetchData = useCallback(async (isRefresh = false) => {
    if (isRefresh) setRefreshing(true);
    try {
      const [statsRes, usageRes, usersRes, revenueRes] = await Promise.allSettled([
        apiGetDashboardStats(),
        apiGetUsage(30),
        apiListUsers(10),
        apiGetRevenueAnalytics(6),
      ]);

      if (statsRes.status === 'fulfilled' && statsRes.value.data) {
        setStats(prev => mergeApiStats(prev, statsRes.value.data!));
      }
      if (usageRes.status === 'fulfilled' && usageRes.value.data?.records?.length) {
        const metrics = usageRecordsToDailyMetrics(usageRes.value.data.records);
        setDailyMetrics(metrics);
        setModelUsage(buildModelUsage(usageRes.value.data.records));
      }
      if (usersRes.status === 'fulfilled' && usersRes.value.data?.users?.length) {
        setRecentUsers(
          usersRes.value.data.users
            .sort((a, b) => b.lastActive.localeCompare(a.lastActive))
            .slice(0, 6)
            .map(u => ({
              id: u.id,
              name: u.name,
              email: u.email,
              plan: u.plan as User['plan'],
              status: u.status as User['status'],
              createdAt: u.createdAt,
              lastActive: u.lastActive,
              totalTokensUsed: u.totalTokensUsed,
              totalRequests: u.totalRequests,
              monthlySpend: u.monthlySpend,
            }))
        );
      }
      if (revenueRes.status === 'fulfilled' && revenueRes.value.data) {
        setRevenue(revenueRes.value.data);
      }
      setLastUpdated(new Date());
    } finally {
      setLoading(false);
      setRefreshing(false);
    }
  }, []);

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

  const kpiCards = buildKpiCards(stats, revenue);
  return (
    <div className="space-y-8">
      {/* Header */}
      <div>
        <PageHeader
          title="Dashboard"
          className="!mb-2"
          actions={
            <Button
              variant="outline"
              size="sm"
              onClick={() => fetchData(true)}
              disabled={refreshing}
            >
              <RefreshCw className={`mr-2 h-4 w-4 ${refreshing ? 'animate-spin' : ''}`} />
              Refresh
            </Button>
          }
        />
        <p className="text-muted-foreground">
          Platform overview and key metrics
          {lastUpdated && (
            <span className="ml-2 text-xs">
              &middot; Updated {lastUpdated.toLocaleTimeString()}
            </span>
          )}
        </p>
      </div>

      {/* KPI Cards */}
      {loading ? (
        <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
          {Array.from({ length: 6 }).map((_, i) => (
            <KpiSkeleton key={i} />
          ))}
        </div>
      ) : (
        <StaggerList
          as="div"
          from="up"
          stagger={50}
          className="grid gap-4 md:grid-cols-2 lg:grid-cols-3"
        >
          {kpiCards.map(card => (
            <Card key={card.title} className="transition-shadow hover:shadow-md">
              <CardHeader className="flex flex-row items-center justify-between pb-2">
                <CardTitle className="text-sm font-medium text-muted-foreground">
                  {card.title}
                </CardTitle>
                <card.icon className="h-4 w-4 text-muted-foreground" />
              </CardHeader>
              <CardContent>
                <div className="text-2xl font-bold">{card.value}</div>
                <div className="flex items-center gap-2 mt-1">
                  <Badge
                    variant={card.title === 'Churn Rate' ? 'default' : 'secondary'}
                    className={`text-xs ${
                      card.trend === 'up' && card.title !== 'Churn Rate'
                        ? 'text-emerald-600 bg-emerald-50'
                        : card.title === 'Churn Rate'
                          ? 'text-emerald-600 bg-emerald-50'
                          : 'text-red-600 bg-red-50'
                    }`}
                  >
                    {card.trend === 'up' && card.title !== 'Churn Rate' ? (
                      <ArrowUpRight className="h-3 w-3 mr-0.5" />
                    ) : (
                      <ArrowDownRight className="h-3 w-3 mr-0.5" />
                    )}
                    {card.change}
                  </Badge>
                  <span className="text-xs text-muted-foreground">{card.subtitle}</span>
                </div>
              </CardContent>
            </Card>
          ))}
        </StaggerList>
      )}

      {/* Charts Row */}
      {loading ? (
        <div className="grid gap-6 lg:grid-cols-2">
          <ChartSkeleton />
          <ChartSkeleton />
        </div>
      ) : (
        <div className="grid gap-6 lg:grid-cols-2">
          {/* Active Users Chart */}
          <Card>
            <CardHeader>
              <CardTitle className="text-base">Daily Active Users (30 days)</CardTitle>
            </CardHeader>
            <CardContent>
              <AreaChart
                values={seriesValues(dailyMetrics, 'activeUsers')}
                width={640}
                height={280}
                className="h-auto w-full"
                ariaLabel="Daily active users over the last 30 days"
              />
            </CardContent>
          </Card>

          {/* Revenue Chart */}
          <Card>
            <CardHeader>
              <CardTitle className="text-base">Daily Revenue (30 days)</CardTitle>
            </CardHeader>
            <CardContent>
              <BarChart
                data={dateBars(dailyMetrics, 'revenue')}
                width={640}
                height={280}
                className="h-auto w-full"
                ariaLabel="Daily revenue over the last 30 days"
              />
            </CardContent>
          </Card>
        </div>
      )}

      {/* Bottom Row: Model Usage + Recent Users */}
      <Reveal from="up" className="grid gap-6 lg:grid-cols-2">
        {/* Model Usage */}
        <Card>
          <CardHeader>
            <CardTitle className="text-base">Model Usage Breakdown</CardTitle>
          </CardHeader>
          <CardContent>
            {modelUsage.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-8 text-center">
                <Cpu className="h-10 w-10 text-muted-foreground/30 mb-3" />
                <p className="text-sm text-muted-foreground">No model usage data yet</p>
                <p className="text-xs text-muted-foreground mt-1">
                  Usage will appear once users start dictating
                </p>
              </div>
            ) : (
              <div className="space-y-4">
                {modelUsage.map(m => (
                  <div key={m.model} className="space-y-2">
                    <div className="flex items-center justify-between text-sm">
                      <span className="font-medium">{m.model}</span>
                      <span className="text-muted-foreground">
                        {formatNumber(m.tokens)} tokens &middot; {formatCurrency(m.cost)}
                      </span>
                    </div>
                    <div className="h-2 rounded-full bg-muted overflow-hidden">
                      <div
                        className="h-full rounded-full bg-primary transition-all"
                        style={{ width: `${m.percentage}%` }}
                      />
                    </div>
                  </div>
                ))}
              </div>
            )}
          </CardContent>
        </Card>

        {/* Recent Users */}
        <Card>
          <CardHeader>
            <CardTitle className="text-base">Recent Users</CardTitle>
          </CardHeader>
          <CardContent>
            {recentUsers.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-8 text-center">
                <Users className="h-10 w-10 text-muted-foreground/30 mb-3" />
                <p className="text-sm text-muted-foreground">No users yet</p>
              </div>
            ) : (
              <div className="space-y-3">
                {recentUsers.map(user => (
                  <div
                    key={user.id}
                    className="flex items-center justify-between rounded-lg p-2 -mx-2 hover:bg-muted/50 transition-colors"
                  >
                    <div className="flex items-center gap-3">
                      <div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary/10 text-xs font-bold text-primary">
                        {user.name
                          .split(' ')
                          .map(n => n[0])
                          .join('')}
                      </div>
                      <div>
                        <p className="text-sm font-medium">{user.name}</p>
                        <p className="text-xs text-muted-foreground">{user.email}</p>
                      </div>
                    </div>
                    <Badge
                      variant="secondary"
                      className={
                        user.plan === 'enterprise'
                          ? 'bg-violet-50 text-violet-700'
                          : user.plan === 'pro'
                            ? 'bg-blue-50 text-blue-700'
                            : ''
                      }
                    >
                      {user.plan}
                    </Badge>
                  </div>
                ))}
              </div>
            )}
          </CardContent>
        </Card>
      </Reveal>
    </div>
  );
}
