import { Ionicons } from "@expo/vector-icons";
import { router } from "expo-router";
import { Pressable, RefreshControl, StyleSheet, Text, View } from "react-native";

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

type ActionItem = {
  key: string;
  title: string;
  detail: string;
  icon: keyof typeof Ionicons.glyphMap;
  tone: "warning" | "primary" | "success";
  onPress: () => void;
};

export default function DashboardScreen() {
  const { colors } = useAppTheme();
  const styles = useThemedStyles(createDashboardStyles);
  const { data: session } = useSession();
  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 home…" />;
  }

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

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

  const now = new Date();
  const running = runningQuery.data;
  const runningClient = running?.client?.name ?? "No client";
  const monthInvoices = stats.monthInvoices ?? [];
  const monthTotal = monthInvoices.reduce((sum, invoice) => sum + invoice.totalAmount, 0);
  const maxRevenue = Math.max(...stats.revenueChartData.map((d) => d.revenue), 1);
  const drafts = stats.recentInvoices.filter((invoice) => invoice.status === "draft");
  const pendingInvoices = monthInvoices.filter((invoice) => {
    const status = getInvoiceStatus(invoice);
    return status === "sent" || status === "overdue";
  });
  const overdueInvoices = monthInvoices.filter((invoice) => getInvoiceStatus(invoice) === "overdue");
  const displayName = session?.user.name?.trim();
  const firstName =
    (displayName ? displayName.split(/\s+/)[0] : undefined) ??
    session?.user.email?.split("@")[0] ??
    "there";

  const actionItems: ActionItem[] = [
    ...(running
      ? [
          {
            key: "running",
            title: "Timer running",
            detail: `${formatElapsedHoursMinutes(runningElapsed)} on ${runningClient}`,
            icon: "timer-outline" as const,
            tone: "success" as const,
            onPress: () => router.push("/(app)/timer"),
          },
        ]
      : []),
    ...(overdueInvoices.length > 0
      ? [
          {
            key: "overdue",
            title: `${overdueInvoices.length} overdue ${overdueInvoices.length === 1 ? "invoice" : "invoices"}`,
            detail: `${formatCurrency(overdueInvoices.reduce((sum, invoice) => sum + invoice.totalAmount, 0))} needs follow-up`,
            icon: "alert-circle-outline" as const,
            tone: "warning" as const,
            onPress: () => router.push("/(app)/invoices"),
          },
        ]
      : []),
    ...(drafts.length > 0
      ? [
          {
            key: "drafts",
            title: `${drafts.length} draft ${drafts.length === 1 ? "invoice" : "invoices"}`,
            detail: "Review and send when ready",
            icon: "document-text-outline" as const,
            tone: "primary" as const,
            onPress: () => router.push("/(app)/invoices"),
          },
        ]
      : []),
    ...(pendingInvoices.length > 0
      ? [
          {
            key: "pending",
            title: `${pendingInvoices.length} awaiting payment`,
            detail: `${formatCurrency(pendingInvoices.reduce((sum, invoice) => sum + invoice.totalAmount, 0))} outstanding this month`,
            icon: "card-outline" as const,
            tone: "primary" as const,
            onPress: () => router.push("/(app)/invoices"),
          },
        ]
      : []),
  ];

  if (actionItems.length === 0) {
    actionItems.push({
      key: "clear",
      title: "No urgent action items",
      detail: "You are clear for the moment",
      icon: "checkmark-circle-outline",
      tone: "success",
      onPress: () => router.push("/(app)/invoices"),
    });
  }

  return (
    <AppBackground>
      <TabPage>
        <TabScrollView
          header={<PageHeader title={`Hello, ${firstName}`} subtitle="What needs attention now" />}
          refreshControl={
            <RefreshControl
              refreshing={statsQuery.isRefetching || runningQuery.isRefetching}
              onRefresh={() => {
                void statsQuery.refetch();
                void runningQuery.refetch();
              }}
              tintColor={colors.primary}
            />
          }
        >
          <View style={styles.quickActions}>
            <Button title="Start timer" onPress={() => router.push("/(app)/timer")} />
            <Button
              title="Invoices"
              variant="secondary"
              onPress={() => router.push("/(app)/invoices")}
            />
            <Button
              title="Reports"
              variant="secondary"
              onPress={() => router.push("/(app)/more/reports" as never)}
            />
          </View>

          <Card title="Action items">
            <View style={styles.actionList}>
              {actionItems.map((item) => (
                <Pressable
                  accessibilityRole="button"
                  key={item.key}
                  onPress={item.onPress}
                  style={({ pressed }) => [styles.actionRow, pressed && styles.pressed]}
                >
                  <View
                    style={[
                      styles.actionIcon,
                      {
                        backgroundColor:
                          item.tone === "warning"
                            ? colors.warningBg
                            : item.tone === "success"
                              ? colors.successBg
                              : colors.muted,
                      },
                    ]}
                  >
                    <Ionicons
                      name={item.icon}
                      size={20}
                      color={
                        item.tone === "warning"
                          ? colors.warning
                          : item.tone === "success"
                            ? colors.success
                            : colors.primary
                      }
                    />
                  </View>
                  <View style={styles.actionCopy}>
                    <Text style={styles.actionTitle}>{item.title}</Text>
                    <Text style={styles.actionDetail}>{item.detail}</Text>
                  </View>
                  <Ionicons name="chevron-forward" size={18} color={colors.mutedForeground} />
                </Pressable>
              ))}
            </View>
          </Card>

          {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}>
                      {resolveClockDescription(running.description)}
                    </Text>
                    <Text style={styles.runningSub}>
                      {runningClient}
                      {running.invoice
                        ? ` · ${running.invoice.invoicePrefix ?? "#"}${running.invoice.invoiceNumber}`
                        : ""}
                    </Text>
                  </View>
                  <Text style={styles.runningTime}>
                    {formatElapsedHoursMinutes(runningElapsed)}
                  </Text>
                </View>
              </GlassSurface>
            </Pressable>
          ) : null}

          <Card
            title={now.toLocaleDateString("en-US", {
              month: "long",
              year: "numeric",
            })}
          >
            <View style={styles.monthSummary}>
              <View>
                <Text style={styles.monthValue}>{formatCurrency(monthTotal)}</Text>
                <Text style={styles.monthLabel}>
                  {monthInvoices.length} {monthInvoices.length === 1 ? "invoice" : "invoices"} this month
                </Text>
              </View>
              <Button
                title="New invoice"
                variant="secondary"
                onPress={() => router.push("/(app)/invoices/new")}
              />
            </View>

            <View style={styles.monthList}>
              {monthInvoices.slice(0, 4).map((invoice) => {
                const status = getInvoiceStatus(invoice);
                return (
                  <Pressable
                    accessibilityRole="button"
                    key={invoice.id}
                    onPress={() => router.push(`/(app)/invoices/${invoice.id}`)}
                    style={({ pressed }) => [styles.monthInvoiceRow, pressed && styles.pressed]}
                  >
                    <View style={styles.invoiceMeta}>
                      <Text style={styles.invoiceTitle}>
                        {invoice.invoicePrefix}
                        {invoice.invoiceNumber}
                      </Text>
                      <Text style={styles.invoiceClient}>{invoice.client?.name ?? "Client"}</Text>
                    </View>
                    <View style={styles.invoiceRight}>
                      <Text style={styles.invoiceAmount}>
                        {formatCurrency(invoice.totalAmount, invoice.currency)}
                      </Text>
                      <StatusBadge status={status} />
                    </View>
                  </Pressable>
                );
              })}
              {monthInvoices.length === 0 ? (
                <Text style={styles.empty}>No invoices in this month yet.</Text>
              ) : null}
            </View>
          </Card>

          {stats.currentDraft ? (
            <GlassSurface style={styles.draftGlass}>
              <Pressable
                style={styles.draftBanner}
                onPress={() => router.push(`/(app)/invoices/${stats.currentDraft!.id}`)}
              >
                <View style={styles.draftCopy}>
                  <Text style={styles.draftTitle}>Current draft</Text>
                  <Text style={styles.draftText}>
                    {stats.currentDraft.client?.name ?? "Client"} ·{" "}
                    {formatCurrency(stats.currentDraft.totalAmount)} ·{" "}
                    {stats.currentDraft.totalHours.toFixed(1)}h logged
                  </Text>
                </View>
                <Ionicons name="chevron-forward" size={18} color={colors.mutedForeground} />
              </Pressable>
            </GlassSurface>
          ) : null}

          <View style={styles.statsGrid}>
            <View style={styles.statCell}>
              <StatCard label="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)} />
            </View>
            <Pressable style={styles.statCell} onPress={() => router.push("/(app)/entities")}>
              <StatCard label="Clients" value={String(stats.totalClients)} />
            </Pressable>
          </View>

          <Card title="Revenue trend">
            <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>
                  </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={({ pressed }) => [styles.recentRow, pressed && styles.pressed]}
                    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({
    actionList: {
      gap: spacing.xs,
    },
    actionRow: {
      flexDirection: "row",
      alignItems: "center",
      gap: spacing.md,
      minHeight: 58,
      paddingVertical: spacing.xs,
    },
    actionIcon: {
      width: 38,
      height: 38,
      borderRadius: radii.md,
      alignItems: "center",
      justifyContent: "center",
    },
    actionCopy: {
      flex: 1,
      gap: 2,
    },
    actionTitle: {
      color: colors.foreground,
      fontFamily: fonts.bodySemiBold,
      fontSize: 15,
      lineHeight: 20,
    },
    actionDetail: {
      color: colors.mutedForeground,
      fontFamily: fonts.body,
      fontSize: 12,
      lineHeight: 16,
    },
    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,
    },
    monthSummary: {
      flexDirection: "row",
      alignItems: "center",
      justifyContent: "space-between",
      gap: spacing.md,
    },
    monthValue: {
      color: colors.foreground,
      fontFamily: fonts.heading,
      fontSize: 24,
      lineHeight: 30,
    },
    monthLabel: {
      color: colors.mutedForeground,
      fontFamily: fonts.bodyMedium,
      fontSize: 12,
      lineHeight: 16,
    },
    monthList: {
      gap: spacing.xs,
    },
    monthInvoiceRow: {
      flexDirection: "row",
      alignItems: "center",
      justifyContent: "space-between",
      gap: spacing.md,
      paddingTop: spacing.sm,
      borderTopWidth: 1,
      borderTopColor: colors.border,
    },
    quickActions: {
      flexDirection: "row",
      gap: spacing.sm,
    },
    draftGlass: {
      borderColor: isDark ? "rgba(59, 130, 246, 0.32)" : "#BFDBFE",
    },
    draftBanner: {
      flexDirection: "row",
      alignItems: "center",
      gap: spacing.md,
      padding: spacing.md,
    },
    draftCopy: {
      flex: 1,
      gap: 3,
    },
    draftTitle: {
      fontFamily: fonts.bodySemiBold,
      color: colors.primary,
      fontSize: 14,
    },
    draftText: {
      fontFamily: fonts.body,
      color: colors.mutedForeground,
      fontSize: 13,
      lineHeight: 18,
    },
    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,
    },
    empty: {
      color: colors.mutedForeground,
      fontSize: 14,
      fontFamily: fonts.body,
      lineHeight: 20,
    },
    recentRow: {
      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,
    },
    pressed: {
      opacity: 0.85,
    },
    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,
    },
  });
