import { useMemo, useState } from "react";
import { RefreshControl, StyleSheet, Text, View } from "react-native";

import { AppBackground } from "@/components/AppBackground";
import { LoadingScreen } from "@/components/LoadingScreen";
import { PageHeader } from "@/components/PageHeader";
import { SwipeableRow } from "@/components/SwipeableRow";
import { TabPage } from "@/components/TabPage";
import { TabScrollView } from "@/components/TabScrollView";
import { TimeEntryEditSheet } from "@/components/time-clock/TimeEntryEditSheet";
import { Card } from "@/components/ui/Card";
import { fonts, spacing } from "@/constants/theme";
import { useAppTheme } from "@/contexts/ThemeContext";
import { formatRunningTimerLabel } from "@/lib/time-clock";
import { formatTrpcErrorMessage } from "@/lib/trpc-errors";
import { api } from "@/lib/trpc";
import type { AppRouter } from "beenvoice/server/api/root";
import type { inferRouterOutputs } from "@trpc/server";

type TimeEntry = inferRouterOutputs<AppRouter>["timeEntries"]["getAll"][number];

function groupByDate(entries: TimeEntry[]) {
  const groups = new Map<string, typeof entries>();
  for (const entry of entries) {
    const d = new Date(entry.startedAt);
    const key = d.toLocaleDateString(undefined, {
      weekday: "long",
      month: "long",
      day: "numeric",
      year: "numeric",
    });
    const list = groups.get(key) ?? [];
    list.push(entry);
    groups.set(key, list);
  }
  return Array.from(groups.entries());
}

export default function TimeEntriesScreen() {
  const { colors } = useAppTheme();
  const [editEntryId, setEditEntryId] = useState<string | null>(null);
  const entriesQuery = api.timeEntries.getAll.useQuery();

  const completed = useMemo(
    () => (entriesQuery.data ?? []).filter((entry) => entry.endedAt),
    [entriesQuery.data],
  );
  const grouped = useMemo(() => groupByDate(completed), [completed]);

  if (entriesQuery.isLoading) {
    return <LoadingScreen message="Loading time entries…" />;
  }

  if (entriesQuery.error) {
    return (
      <AppBackground>
        <TabPage>
          <Text style={{ color: colors.mutedForeground, padding: spacing.lg }}>
            {formatTrpcErrorMessage(entriesQuery.error)}
          </Text>
        </TabPage>
      </AppBackground>
    );
  }

  return (
    <AppBackground>
      <TabPage>
        <TabScrollView
          header={
            <PageHeader title="Time entries" subtitle={`${completed.length} completed entries`} />
          }
          refreshControl={
            <RefreshControl
              refreshing={entriesQuery.isRefetching}
              onRefresh={() => void entriesQuery.refetch()}
              tintColor={colors.primary}
            />
          }
        >
          {grouped.length === 0 ? (
            <Text style={{ color: colors.mutedForeground, fontFamily: fonts.body }}>
              No completed entries yet. Start the timer from the Timer tab.
            </Text>
          ) : (
            grouped.map(([label, entries]) => (
              <Card key={label} title={label}>
                {entries.map((entry) => (
                  <SwipeableRow
                    key={entry.id}
                    actions={[
                      {
                        key: "edit",
                        label: "Edit",
                        icon: "create-outline",
                        color: "#fff",
                        backgroundColor: colors.primary,
                        onPress: () => setEditEntryId(entry.id),
                      },
                    ]}
                  >
                    <View style={styles.row}>
                      <View style={{ flex: 1, gap: 2 }}>
                        <Text style={[styles.title, { color: colors.foreground }]}>
                          {formatRunningTimerLabel(entry.description)}
                        </Text>
                        <Text style={{ color: colors.mutedForeground, fontFamily: fonts.body }}>
                          {entry.client?.name ?? "No client"}
                          {entry.invoice
                            ? ` · ${entry.invoice.invoicePrefix ?? "#"}${entry.invoice.invoiceNumber}`
                            : " · not billed"}
                        </Text>
                      </View>
                      <Text style={[styles.title, { color: colors.foreground }]}>
                        {entry.hours ?? "—"}h
                      </Text>
                    </View>
                  </SwipeableRow>
                ))}
              </Card>
            ))
          )}
        </TabScrollView>
      </TabPage>

      <TimeEntryEditSheet
        entryId={editEntryId}
        visible={editEntryId != null}
        onClose={() => setEditEntryId(null)}
      />
    </AppBackground>
  );
}

const styles = StyleSheet.create({
  row: {
    flexDirection: "row",
    gap: spacing.md,
    paddingVertical: spacing.sm,
  },
  title: {
    fontFamily: fonts.bodySemiBold,
    fontSize: 14,
  },
});
