import { router } from "expo-router";
import { Pressable, RefreshControl, StyleSheet, Text, View } from "react-native";
import { Screen } from "@/components/Screen";
import { TabPage } from "@/components/TabPage";
import { TabScrollView } from "@/components/TabScrollView";

import { AppBackground } from "@/components/AppBackground";
import { PageHeader } from "@/components/PageHeader";
import { GlassSurface } from "@/components/GlassSurface";
import { LoadingScreen } from "@/components/LoadingScreen";
import { StatCard } from "@/components/StatCard";
import { StatusBadge } from "@/components/StatusBadge";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { fonts, radii, spacing } from "@/constants/theme";
import { useAppTheme } from "@/contexts/ThemeContext";
import { formatCurrency, formatDate } from "@/lib/format";
import type { ThemeColors } from "@/lib/theme-palette";
import { useThemedStyles } from "@/lib/use-themed-styles";
import { getInvoiceStatus } from "@/lib/invoice-status";
import { formatElapsedHoursMinutes } from "@/lib/time-clock";
import { useRunningElapsed } from "@/lib/use-running-elapsed";
import { api } from "@/lib/trpc";

export default function DashboardScreen() {
  const { colors } = useAppTheme();
  const styles = useThemedStyles(createDashboardStyles);
  const statsQuery = api.dashboard.getStats.useQuery();
  const runningQuery = api.timeEntries.getRunning.useQuery(undefined, {
    refetchInterval: 30_000,
  });
  const runningElapsed = useRunningElapsed(runningQuery.data?.startedAt);

  if (statsQuery.isLoading) {
    return <LoadingScreen message="Loading dashboard…" />;
  }

  if (statsQuery.error) {
    return (
      <AppBackground>
        <Screen>
          <View style={styles.errorBox}>
            <Text style={styles.errorTitle}>Could not load dashboard</Text>
            <Text style={styles.errorText}>{statsQuery.error.message}</Text>
          </View>
        </Screen>
      </AppBackground>
    );
  }

  const stats = statsQuery.data;
  if (!stats) {
    return <LoadingScreen message="Loading dashboard…" />;
  }

  const running = runningQuery.data;
  const revenueChange =
    stats.revenueChange > 0
      ? `+${stats.revenueChange.toFixed(0)}% vs last month`
      : stats.revenueChange < 0
        ? `${stats.revenueChange.toFixed(0)}% vs last month`
        : "No change vs last month";

  const maxRevenue = Math.max(...stats.revenueChartData.map((d) => d.revenue), 1);

  return (
    <AppBackground>
      <TabPage>
        <TabScrollView
          header={
            <PageHeader title="Overview" subtitle="Your invoicing at a glance" />
          }
          refreshControl={
            <RefreshControl
              refreshing={statsQuery.isRefetching || runningQuery.isRefetching}
              onRefresh={() => {
                void statsQuery.refetch();
                void runningQuery.refetch();
              }}
              tintColor={colors.primary}
            />
          }
        >
          {running ? (
            <Pressable onPress={() => router.push("/(app)/timer")}>
              <GlassSurface style={styles.runningGlass}>
                <View style={styles.runningRow}>
                  <View style={styles.runningDot} />
                  <View style={styles.runningMeta}>
                    <Text style={styles.runningTitle}>
                      {running.description || "Timer running"}
                    </Text>
                    <Text style={styles.runningSub}>
                      {running.client?.name ?? "No client"}
                      {running.invoice
                        ? ` · ${running.invoice.invoicePrefix ?? "#"}${running.invoice.invoiceNumber}`
                        : ""}
                    </Text>
                  </View>
                  <Text style={styles.runningTime}>
                    {formatElapsedHoursMinutes(runningElapsed)}
                  </Text>
                </View>
              </GlassSurface>
            </Pressable>
          ) : null}

          {stats.overdueCount > 0 ? (
            <GlassSurface style={styles.alertGlass}>
              <View style={styles.alertBanner}>
                <Text style={styles.alertTitle}>
                  {stats.overdueCount} overdue {stats.overdueCount === 1 ? "invoice" : "invoices"}
                </Text>
                <Text style={styles.alertText}>
                  Follow up on outstanding payments from the Invoices tab.
                </Text>
              </View>
            </GlassSurface>
          ) : null}

          <View style={styles.quickActions}>
            <Button title="Start timer" onPress={() => router.push("/(app)/timer")} />
            <Button
              title="View invoices"
              variant="secondary"
              onPress={() => router.push("/(app)/invoices")}
            />
          </View>

          <View style={styles.statsGrid}>
            <View style={styles.statCell}>
              <StatCard label="Total revenue" value={formatCurrency(stats.totalRevenue)} />
            </View>
            <View style={styles.statCell}>
              <StatCard label="Pending" value={formatCurrency(stats.pendingAmount)} />
            </View>
            <View style={styles.statCell}>
              <StatCard
                label="Overdue"
                value={String(stats.overdueCount)}
                hint={stats.overdueCount === 1 ? "invoice" : "invoices"}
              />
            </View>
            <Pressable style={styles.statCell} onPress={() => router.push("/(app)/entities")}>
              <StatCard
                label="Clients"
                value={String(stats.totalClients)}
                hint={revenueChange}
              />
            </Pressable>
          </View>

          <Card title="Revenue (6 months)">
            <View style={styles.chart}>
              {stats.revenueChartData.map((point) => {
                const barHeight = Math.max(4, (point.revenue / maxRevenue) * 80);
                return (
                  <View key={point.month} style={styles.chartColumn}>
                    <View style={styles.chartBarTrack}>
                      <View style={[styles.chartBar, { height: barHeight }]} />
                    </View>
                    <Text style={styles.chartLabel}>{point.monthLabel}</Text>
                    <Text style={styles.chartValue}>
                      {point.revenue > 0 ? formatCurrency(point.revenue) : "—"}
                    </Text>
                  </View>
                );
              })}
            </View>
          </Card>

          <Card title="Recent invoices">
            {stats.recentInvoices.length === 0 ? (
              <Text style={styles.empty}>No invoices yet. Create one from the Invoices tab.</Text>
            ) : (
              stats.recentInvoices.map((invoice) => {
                const status = getInvoiceStatus(invoice);
                return (
                  <Pressable
                    key={invoice.id}
                    style={styles.invoiceRow}
                    onPress={() => router.push(`/(app)/invoices/${invoice.id}`)}
                  >
                    <View style={styles.invoiceMeta}>
                      <Text style={styles.invoiceTitle}>
                        {invoice.invoicePrefix}
                        {invoice.invoiceNumber}
                      </Text>
                      <Text style={styles.invoiceClient}>
                        {invoice.client?.name ?? "Client"}
                      </Text>
                      <Text style={styles.invoiceDate}>{formatDate(invoice.issueDate)}</Text>
                    </View>
                    <View style={styles.invoiceRight}>
                      <Text style={styles.invoiceAmount}>
                        {formatCurrency(invoice.totalAmount, invoice.currency)}
                      </Text>
                      <StatusBadge status={status} />
                    </View>
                  </Pressable>
                );
              })
            )}
          </Card>
        </TabScrollView>
      </TabPage>
    </AppBackground>
  );
}

const createDashboardStyles = (colors: ThemeColors, isDark: boolean) =>
  StyleSheet.create({
  safe: {
    flex: 1,
  },
  runningGlass: {
    borderColor: isDark ? "rgba(74, 222, 128, 0.35)" : "#BBF7D0",
  },
  runningRow: {
    flexDirection: "row",
    alignItems: "center",
    gap: spacing.md,
    padding: spacing.md,
  },
  runningDot: {
    width: 10,
    height: 10,
    borderRadius: 5,
    backgroundColor: colors.success,
  },
  runningMeta: {
    flex: 1,
    gap: 2,
  },
  runningTitle: {
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
    fontSize: 14,
  },
  runningSub: {
    fontFamily: fonts.body,
    color: colors.mutedForeground,
    fontSize: 12,
  },
  runningTime: {
    fontFamily: fonts.mono,
    fontSize: 18,
    color: colors.success,
  },
  alertBanner: {
    padding: spacing.md,
    gap: 4,
  },
  alertGlass: {
    borderColor: isDark ? "rgba(251, 191, 36, 0.4)" : "#FDE68A",
  },
  alertTitle: {
    fontFamily: fonts.bodySemiBold,
    color: colors.warning,
    fontSize: 14,
  },
  alertText: {
    fontFamily: fonts.body,
    color: colors.mutedForeground,
    fontSize: 13,
  },
  quickActions: {
    flexDirection: "row",
    gap: spacing.sm,
  },
  statsGrid: {
    flexDirection: "row",
    flexWrap: "wrap",
    gap: spacing.md,
    alignContent: "flex-start",
  },
  statCell: {
    flexGrow: 0,
    flexShrink: 0,
    flexBasis: "47%",
  },
  chart: {
    flexDirection: "row",
    justifyContent: "space-between",
    gap: spacing.xs,
  },
  chartColumn: {
    flex: 1,
    alignItems: "center",
    gap: 4,
  },
  chartBarTrack: {
    width: "100%",
    height: 80,
    justifyContent: "flex-end",
    alignItems: "center",
  },
  chartBar: {
    width: "70%",
    minHeight: 4,
    backgroundColor: colors.primary,
    borderRadius: radii.sm,
  },
  chartLabel: {
    fontSize: 10,
    fontFamily: fonts.bodyMedium,
    color: colors.mutedForeground,
  },
  chartValue: {
    fontSize: 9,
    fontFamily: fonts.body,
    color: colors.mutedForeground,
    textAlign: "center",
  },
  empty: {
    color: colors.mutedForeground,
    fontSize: 14,
    fontFamily: fonts.body,
    lineHeight: 20,
  },
  invoiceRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    gap: spacing.md,
    paddingVertical: spacing.sm,
    borderTopWidth: 1,
    borderTopColor: colors.border,
  },
  invoiceMeta: {
    flex: 1,
    gap: 2,
  },
  invoiceTitle: {
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
    fontSize: 15,
  },
  invoiceClient: {
    color: colors.mutedForeground,
    fontSize: 14,
    fontFamily: fonts.body,
  },
  invoiceDate: {
    color: colors.mutedForeground,
    fontSize: 12,
    fontFamily: fonts.body,
  },
  invoiceRight: {
    alignItems: "flex-end",
    gap: spacing.sm,
  },
  invoiceAmount: {
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
    fontSize: 15,
  },
  errorBox: {
    flex: 1,
    justifyContent: "center",
    padding: spacing.lg,
    gap: spacing.sm,
  },
  errorTitle: {
    fontSize: 18,
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
  },
  errorText: {
    color: colors.mutedForeground,
    fontFamily: fonts.body,
    lineHeight: 20,
  },
});
