import { router } from "expo-router";
import { useState } from "react";
import {
  Alert,
  Pressable,
  RefreshControl,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from "react-native";

import { AppBackground } from "@/components/AppBackground";
import { FilterChip } from "@/components/FilterChip";
import { FloatingActionButton } from "@/components/FloatingActionButton";
import { GlassSurface } from "@/components/GlassSurface";
import { LoadingScreen } from "@/components/LoadingScreen";
import { PageHeader } from "@/components/PageHeader";
import { StatusBadge } from "@/components/StatusBadge";
import { TabPage } from "@/components/TabPage";
import { TabScrollView } from "@/components/TabScrollView";
import { fonts, 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, type InvoiceStatus } from "@/lib/invoice-status";
import { api } from "@/lib/trpc";

const filters: Array<{ label: string; value?: InvoiceStatus | "all" }> = [
  { label: "All", value: "all" },
  { label: "Draft", value: "draft" },
  { label: "Sent", value: "sent" },
  { label: "Paid", value: "paid" },
  { label: "Overdue", value: "overdue" },
];

export default function InvoicesScreen() {
  const { colors } = useAppTheme();
  const styles = useThemedStyles(createInvoicesStyles);
  const [filter, setFilter] = useState<(typeof filters)[number]["value"]>("all");
  const utils = api.useUtils();
  const invoicesQuery = api.invoices.getAll.useQuery();
  const updateStatus = api.invoices.updateStatus.useMutation({
    onSuccess: () => {
      utils.invoices.getAll.invalidate();
      utils.dashboard.getStats.invalidate();
    },
    onError: (err) => Alert.alert("Update failed", err.message),
  });

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

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

  const invoices = (invoicesQuery.data ?? []).filter((invoice) => {
    if (filter === "all") return true;
    return getInvoiceStatus(invoice) === filter;
  });

  function promptStatusChange(invoiceId: string, current: InvoiceStatus) {
    const options: Array<{ label: string; status: "draft" | "sent" | "paid" }> = [];

    if (current !== "draft") options.push({ label: "Mark as draft", status: "draft" });
    if (current !== "sent" && current !== "overdue") {
      options.push({ label: "Mark as sent", status: "sent" });
    }
    if (current !== "paid") options.push({ label: "Mark as paid", status: "paid" });

    if (options.length === 0) return;

    Alert.alert("Update status", "Choose a new status", [
      ...options.map((option) => ({
        text: option.label,
        onPress: () => {
          updateStatus.mutate({ id: invoiceId, status: option.status });
        },
      })),
      { text: "Cancel", style: "cancel" },
    ]);
  }

  return (
    <AppBackground>
      <TabPage>
        <TabScrollView
          header={
            <PageHeader title="Invoices" subtitle="Review status, amounts, and due dates" />
          }
          refreshControl={
            <RefreshControl
              refreshing={invoicesQuery.isRefetching}
              onRefresh={() => invoicesQuery.refetch()}
              tintColor={colors.primary}
            />
          }
        >
          <ScrollView
            horizontal
            showsHorizontalScrollIndicator={false}
            style={styles.filterScroll}
            contentContainerStyle={styles.filters}
          >
            {filters.map((item) => (
              <FilterChip
                key={item.label}
                label={item.label}
                active={filter === item.value}
                onPress={() => setFilter(item.value)}
              />
            ))}
          </ScrollView>

          {invoices.length === 0 ? (
            <View style={styles.empty}>
              <Text style={styles.emptyTitle}>No invoices found</Text>
              <Text style={styles.emptyText}>
                Tap + to create your first invoice, or pull to refresh.
              </Text>
            </View>
          ) : (
            invoices.map((invoice) => {
              const status = getInvoiceStatus(invoice);
              return (
                <Pressable
                  key={invoice.id}
                  onPress={() => router.push(`/(app)/invoices/${invoice.id}`)}
                  onLongPress={() => promptStatusChange(invoice.id, status)}
                >
                  <GlassSurface style={styles.card}>
                    <View style={styles.cardInner}>
                      <View style={styles.cardTop}>
                        <View style={styles.cardMeta}>
                          <Text style={styles.invoiceNumber}>
                            {invoice.invoicePrefix}
                            {invoice.invoiceNumber}
                          </Text>
                          <Text style={styles.clientName}>
                            {invoice.client?.name ?? "Client"}
                          </Text>
                        </View>
                        <Text style={styles.amount}>
                          {formatCurrency(invoice.totalAmount, invoice.currency)}
                        </Text>
                      </View>
                      <View style={styles.cardBottom}>
                        <Text style={styles.date}>Due {formatDate(invoice.dueDate)}</Text>
                        <StatusBadge status={status} />
                      </View>
                    </View>
                  </GlassSurface>
                </Pressable>
              );
            })
          )}
        </TabScrollView>
        <FloatingActionButton
          accessibilityLabel="Create invoice"
          onPress={() => {
            Alert.alert("Create invoice", "Choose how to start", [
              { text: "Cancel", style: "cancel" },
              {
                text: "With line items",
                onPress: () => router.push("/(app)/invoices/new"),
              },
              {
                text: "Blank (for timer)",
                onPress: () => router.push("/(app)/invoices/new?blank=1"),
              },
            ]);
          }}
        />
      </TabPage>
    </AppBackground>
  );
}

const createInvoicesStyles = (colors: ThemeColors, _isDark: boolean) =>
  StyleSheet.create({
  filterScroll: {
    flexGrow: 0,
    marginBottom: spacing.sm,
  },
  filters: {
    gap: spacing.sm,
    paddingRight: spacing.md,
  },
  card: {},
  cardInner: {
    padding: spacing.md,
    gap: spacing.md,
  },
  cardTop: {
    flexDirection: "row",
    justifyContent: "space-between",
    gap: spacing.md,
  },
  cardMeta: {
    flex: 1,
    gap: 4,
  },
  invoiceNumber: {
    fontSize: 16,
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
  },
  clientName: {
    color: colors.mutedForeground,
    fontSize: 14,
    fontFamily: fonts.body,
  },
  amount: {
    fontSize: 16,
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
  },
  cardBottom: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
  },
  date: {
    color: colors.mutedForeground,
    fontSize: 13,
    fontFamily: fonts.body,
  },
  empty: {
    padding: spacing.lg,
    alignItems: "center",
    gap: spacing.sm,
  },
  emptyTitle: {
    fontSize: 18,
    fontFamily: fonts.bodySemiBold,
    color: colors.foreground,
  },
  emptyText: {
    textAlign: "center",
    color: colors.mutedForeground,
    fontFamily: fonts.body,
    lineHeight: 20,
  },
  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,
  },
});
