import { useEffect, useMemo, useState, type ReactNode } from "react";
import {
  Alert,
  Pressable,
  RefreshControl,
  StyleSheet,
  Text,
  TextInput,
  View,
} from "react-native";
import { router } from "expo-router";

import { FilterChip } from "@/components/FilterChip";
import { GlassSurface } from "@/components/GlassSurface";
import { LoadingScreen } from "@/components/LoadingScreen";
import { TabScrollView } from "@/components/TabScrollView";
import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { DateTimeField } from "@/components/ui/DateTimeField";
import { Input } from "@/components/ui/Input";
import { fonts, spacing } from "@/constants/theme";
import { useAccounts } from "@/contexts/AccountsContext";
import { useAppTheme } from "@/contexts/ThemeContext";
import { formatCurrency, formatDateTime } from "@/lib/format";
import { parseNonNegativeNumber } from "@/lib/form-validation";
import type { ThemeColors } from "@/lib/theme-palette";
import {
  getLastTimeClockClientId,
  setLastTimeClockClientId,
} from "@/lib/time-clock-prefs";
import { useThemedStyles } from "@/lib/use-themed-styles";
import {
  endTimeClockLiveActivity,
} from "@/lib/time-clock-live-activity";
import {
  DEFAULT_CLOCK_DESCRIPTION,
  describeClockOutOutcome,
  formatElapsedSeconds,
  formatRunningTimerLabel,
  resolveClockDescription,
  resolveEffectiveHourlyRate,
  startedAtFromMinutesAgo,
} from "@/lib/time-clock";
import { useRunningElapsed } from "@/lib/use-running-elapsed";
import { api } from "@/lib/trpc";

export type TimeClockPanelProps = {
  defaultClientId?: string;
  defaultInvoiceId?: string;
  compact?: boolean;
  header?: ReactNode;
};

type ClientRow = {
  id: string;
  name: string;
  defaultHourlyRate: number | null;
  currency?: string;
};

type StartMode = "now" | "at" | "ago";

const AGO_PRESETS = [
  { label: "15m", minutes: 15 },
  { label: "30m", minutes: 30 },
  { label: "1h", minutes: 60 },
  { label: "2h", minutes: 120 },
  { label: "4h", minutes: 240 },
] as const;

function clientRateText(client: ClientRow | undefined): string {
  return client?.defaultHourlyRate != null ? String(client.defaultHourlyRate) : "";
}

export function TimeClockPanel({
  defaultClientId = "",
  defaultInvoiceId = "",
  compact = false,
  header,
}: TimeClockPanelProps) {
  const { colors } = useAppTheme();
  const styles = useThemedStyles(createTimeClockStyles);
  const { activeAccountId } = useAccounts();
  const utils = api.useUtils();
  const runningQuery = api.timeEntries.getRunning.useQuery(undefined, {
    refetchInterval: 30_000,
  });
  const clientsQuery = api.clients.getAll.useQuery();

  const [clientId, setClientId] = useState(defaultClientId);
  const [invoiceId, setInvoiceId] = useState(defaultInvoiceId);
  const [description, setDescription] = useState("");
  const [stopNote, setStopNote] = useState("");
  const [rateText, setRateText] = useState("");
  const [startedAt, setStartedAt] = useState(() => new Date());
  const [startMode, setStartMode] = useState<StartMode>("now");
  const [agoMinutes, setAgoMinutes] = useState(60);
  const [agoMinutesText, setAgoMinutesText] = useState("60");
  const [optionsExpanded, setOptionsExpanded] = useState(false);
  const [clientsExpanded, setClientsExpanded] = useState(false);
  const [featuredClientIds, setFeaturedClientIds] = useState<string[]>([]);
  const [storedLastClientId, setStoredLastClientId] = useState<string | null>(null);
  const [prefsLoaded, setPrefsLoaded] = useState(false);
  const [initialClientResolved, setInitialClientResolved] = useState(Boolean(defaultClientId));

  const running = runningQuery.data;
  const elapsed = useRunningElapsed(running?.startedAt);
  const clients = clientsQuery.data ?? [];
  const activeClientId = running?.clientId ?? clientId;

  const billableQuery = api.invoices.getBillable.useQuery(
    activeClientId ? { clientId: activeClientId } : undefined,
  );
  const billableInvoices = billableQuery.data ?? [];

  const todayStart = useMemo(() => {
    const d = new Date();
    d.setHours(0, 0, 0, 0);
    return d;
  }, []);

  const entriesQuery = api.timeEntries.getAll.useQuery();

  const recentClientIds = useMemo(() => {
    const seen = new Set<string>();
    const ids: string[] = [];
    for (const entry of entriesQuery.data ?? []) {
      if (entry.clientId && !seen.has(entry.clientId)) {
        seen.add(entry.clientId);
        ids.push(entry.clientId);
        if (ids.length >= 2) break;
      }
    }
    return ids;
  }, [entriesQuery.data]);

  const clockIn = api.timeEntries.clockIn.useMutation({
    onSuccess: async () => {
      await utils.timeEntries.getRunning.invalidate();
    },
  });

  const clockOut = api.timeEntries.clockOut.useMutation({
    onSuccess: async (data) => {
      await endTimeClockLiveActivity();
      if (running?.clientId && activeAccountId) {
        await setLastTimeClockClientId(activeAccountId, running.clientId);
      }
      const message = describeClockOutOutcome({
        outcome: data.outcome,
        hours: data.hours,
        rate: data.rate,
        invoice: data.invoice,
      });
      Alert.alert(
        data.outcome === "linked_to_invoice" ? "Time logged" : "Timer stopped",
        message,
      );
      await Promise.all([
        utils.timeEntries.getRunning.invalidate(),
        utils.timeEntries.getAll.invalidate(),
        utils.invoices.getAll.invalidate(),
        utils.invoices.getBillable.invalidate(),
        utils.dashboard.getStats.invalidate(),
      ]);
      setDescription("");
      setStopNote("");
    },
  });

  useEffect(() => {
    if (!activeAccountId) {
      setPrefsLoaded(true);
      return;
    }
    setPrefsLoaded(false);
    void getLastTimeClockClientId(activeAccountId).then((id) => {
      setStoredLastClientId(id);
      setPrefsLoaded(true);
    });
  }, [activeAccountId]);

  useEffect(() => {
    if (!running) return;
    setClientId(running.clientId ?? "");
    setInvoiceId(running.invoiceId ?? "");
    setStopNote("");
    setRateText(running.rate != null ? String(running.rate) : "");
  }, [running]);

  useEffect(() => {
    if (!clientId || running || clients.length === 0) return;
    const client = clients.find((c) => c.id === clientId);
    if (!client?.defaultHourlyRate) return;
    setRateText((current) => current.trim() || clientRateText(client));
  }, [clientId, clients, running]);

  useEffect(() => {
    if (running || defaultClientId || initialClientResolved) return;
    if (!prefsLoaded || clients.length === 0) return;

    const preferredId =
      storedLastClientId && clients.some((client) => client.id === storedLastClientId)
        ? storedLastClientId
        : recentClientIds.find((id) => clients.some((client) => client.id === id)) ?? null;

    if (preferredId) {
      const client = clients.find((c) => c.id === preferredId);
      setClientId(preferredId);
      setRateText(clientRateText(client));
    }

    setInitialClientResolved(true);
  }, [
    clients,
    defaultClientId,
    initialClientResolved,
    prefsLoaded,
    recentClientIds,
    running,
    storedLastClientId,
  ]);

  useEffect(() => {
    if (featuredClientIds.length > 0 || !prefsLoaded || clients.length === 0) return;

    const ids: string[] = [];
    const add = (id: string | null | undefined) => {
      if (!id || ids.includes(id)) return;
      if (!clients.some((client) => client.id === id)) return;
      ids.push(id);
    };

    add(storedLastClientId);
    for (const id of recentClientIds) add(id);

    setFeaturedClientIds(ids.slice(0, 1));
  }, [clients, featuredClientIds.length, prefsLoaded, recentClientIds, storedLastClientId]);

  const selectedClient = clients.find((client) => client.id === clientId);
  const rateCurrency = selectedClient?.currency ?? "USD";
  const effectiveRate = resolveEffectiveHourlyRate(
    rateText,
    selectedClient?.defaultHourlyRate,
  );
  const displayRate = running
    ? (running.rate ?? effectiveRate ?? 0)
    : (effectiveRate ?? 0);

  const featuredClients = useMemo(
    () =>
      featuredClientIds
        .map((id) => clients.find((client) => client.id === id))
        .filter((client) => client != null),
    [clients, featuredClientIds],
  );

  const moreClients = useMemo(() => {
    const featuredIds = new Set(featuredClientIds);
    return clients
      .filter((client) => !featuredIds.has(client.id))
      .sort((a, b) => a.name.localeCompare(b.name));
  }, [clients, featuredClientIds]);

  const resolvedStartAt = useMemo(() => {
    if (startMode === "now") return new Date();
    if (startMode === "ago") return startedAtFromMinutesAgo(agoMinutes);
    return startedAt;
  }, [agoMinutes, startMode, startedAt]);

  const clockInErrors = useMemo(() => {
    const next: { clientId?: string; rate?: string; start?: string } = {};
    if (!clientId) next.clientId = "Choose a client to start";
    if (rateText.trim() && parseNonNegativeNumber(rateText) === null) {
      next.rate = "Enter a valid hourly rate";
    }
    if (startMode === "ago" && agoMinutes <= 0) {
      next.start = "Enter how long ago you started";
    }
    return next;
  }, [agoMinutes, clientId, rateText, startMode]);

  const canClockIn = Object.keys(clockInErrors).length === 0;

  const optionsSummary = useMemo(() => {
    const rate =
      effectiveRate ??
      (selectedClient?.defaultHourlyRate != null ? selectedClient.defaultHourlyRate : null);
    const rateLabel = rate != null ? `${formatCurrency(rate, rateCurrency)}/hr` : "No rate";
    const startLabel = startMode === "now" ? "Starting now" : formatDateTime(resolvedStartAt);
    return `${rateLabel} · ${startLabel}`;
  }, [effectiveRate, rateCurrency, resolvedStartAt, selectedClient?.defaultHourlyRate, startMode]);

  const todayEntries = useMemo(
    () =>
      (entriesQuery.data ?? []).filter(
        (entry) => entry.endedAt && new Date(entry.startedAt) >= todayStart,
      ),
    [entriesQuery.data, todayStart],
  );

  async function persistClientChoice(nextClientId: string, syncState = false) {
    if (!activeAccountId || !nextClientId) return;
    await setLastTimeClockClientId(activeAccountId, nextClientId);
    if (syncState) setStoredLastClientId(nextClientId);
  }

  function selectClient(nextClientId: string) {
    const client = clients.find((c) => c.id === nextClientId);
    setClientId(nextClientId);
    setInvoiceId("");
    setRateText(clientRateText(client));
    if (!featuredClientIds.includes(nextClientId)) {
      setClientsExpanded(true);
    }
    void persistClientChoice(nextClientId);
  }

  function selectStartMode(mode: StartMode) {
    setStartMode(mode);
    if (mode !== "now") setOptionsExpanded(true);
    if (mode === "now") {
      setStartedAt(new Date());
      return;
    }
    if (mode === "ago") {
      setStartedAt(startedAtFromMinutesAgo(agoMinutes));
      return;
    }
    setStartedAt((current) =>
      Math.abs(Date.now() - current.getTime()) < 60_000 ? current : new Date(),
    );
  }

  function selectAgoPreset(minutes: number) {
    setStartMode("ago");
    setAgoMinutes(minutes);
    setAgoMinutesText(String(minutes));
    setStartedAt(startedAtFromMinutesAgo(minutes));
  }

  function handleAgoMinutesChange(text: string) {
    setAgoMinutesText(text);
    const parsed = Number(text);
    if (!Number.isNaN(parsed) && parsed > 0) {
      setAgoMinutes(parsed);
      setStartedAt(startedAtFromMinutesAgo(parsed));
    }
  }

  async function handleClockIn() {
    if (!canClockIn) {
      if (clockInErrors.rate || clockInErrors.start) setOptionsExpanded(true);
      return;
    }
    try {
      const backdated =
        startMode === "now" ? undefined : resolvedStartAt;
      await clockIn.mutateAsync({
        description: resolveClockDescription(description),
        clientId: clientId || "",
        invoiceId: invoiceId || undefined,
        rate: effectiveRate ?? undefined,
        startedAt: backdated,
      });
      await persistClientChoice(clientId);
      setStartMode("now");
      setStartedAt(new Date());
      setAgoMinutes(60);
      setAgoMinutesText("60");
    } catch (err) {
      Alert.alert("Clock in failed", err instanceof Error ? err.message : "Try again");
    }
  }

  async function handleClockOut() {
    try {
      await clockOut.mutateAsync({
        description: stopNote.trim() ? stopNote.trim() : undefined,
      });
    } catch (err) {
      Alert.alert("Clock out failed", err instanceof Error ? err.message : "Try again");
    }
  }


  if (runningQuery.isLoading || clientsQuery.isLoading) {
    return <LoadingScreen message="Loading time clock…" />;
  }

  const runningTitle = formatRunningTimerLabel(running?.description);
  const runningMeta = [
    running?.client?.name ?? (running ? "No client" : null),
    running?.invoice
      ? `${running.invoice.invoicePrefix ?? "#"}${running.invoice.invoiceNumber}`
      : null,
    displayRate ? `$${displayRate}/hr` : null,
  ]
    .filter(Boolean)
    .join(" · ");


  function renderClientChip(client: (typeof clients)[number]) {
    return (
      <FilterChip
        key={client.id}
        label={client.name}
        active={clientId === client.id}
        onPress={() => selectClient(client.id)}
      />
    );
  }

  return (
    <TabScrollView
      style={styles.scroll}
      header={header}
      refreshControl={
        <RefreshControl
          refreshing={runningQuery.isRefetching}
          onRefresh={() => {
            void runningQuery.refetch();
            void clientsQuery.refetch();
            void billableQuery.refetch();
            void entriesQuery.refetch();
          }}
          tintColor={colors.primary}
        />
      }
    >
      {running || !compact ? (
        <GlassSurface style={running ? styles.runningCard : undefined}>
          <View style={[styles.hero, running && styles.heroRunning]}>
            {running ? (
              <>
                <View style={styles.heroHeader}>
                  <View style={styles.pulseDot} />
                  <Text style={styles.heroLabelRunning}>Timer running</Text>
                </View>
                <Text style={styles.timerValue}>{formatElapsedSeconds(elapsed)}</Text>
                <Text style={styles.runningTitle}>{runningTitle}</Text>
                {runningMeta ? (
                  <Text style={styles.runningMeta}>{runningMeta}</Text>
                ) : null}
              </>
            ) : (
              <Text style={styles.idleHint}>
                Choose a client and clock in. A draft invoice is created automatically if needed.
              </Text>
            )}
          </View>
        </GlassSurface>
      ) : null}

      <GlassSurface style={styles.setupCard}>
        <Text style={styles.cardTitle}>{running ? "Update & stop" : "Clock in"}</Text>

        {running ? (
          <View style={styles.formSection}>
            <Input
              label="Note on stop (optional)"
              value={stopNote}
              onChangeText={setStopNote}
              placeholder={
                running.description?.trim()
                  ? running.description
                  : "Update description when you stop"
              }
              returnKeyType="done"
            />
            <Button
              title={clockOut.isPending ? "Stopping…" : "Stop & save"}
              variant="danger"
              loading={clockOut.isPending}
              onPress={handleClockOut}
            />
          </View>
        ) : (
          <>
        <TextInput
          value={description}
          onChangeText={setDescription}
          placeholder="What are you working on?"
          placeholderTextColor={colors.mutedForeground}
          returnKeyType="done"
          style={[styles.titleField, { color: colors.foreground }]}
        />

        <View style={styles.setupSection}>
          <Text style={styles.sectionLabel}>Client</Text>
          {clients.length === 0 ? (
            <Text style={styles.emptyClients}>
              Add a client first to start tracking time.
            </Text>
          ) : (
            <>
              <View style={styles.chipWrap}>
                {featuredClients.map((client) => renderClientChip(client))}
                {moreClients.length > 0 ? (
                  <FilterChip
                    label={clientsExpanded ? "Show less" : "Show more"}
                    active={clientsExpanded}
                    onPress={() => setClientsExpanded((open) => !open)}
                  />
                ) : null}
              </View>
              {clientsExpanded && moreClients.length > 0 ? (
                <View style={[styles.chipWrap, styles.moreClientsWrap]}>
                  {moreClients.map((client) => renderClientChip(client))}
                </View>
              ) : null}
            </>
          )}
          {clockInErrors.clientId ? (
            <Text style={styles.fieldError}>{clockInErrors.clientId}</Text>
          ) : null}
        </View>

        {clientId ? (
          <View style={styles.setupSection}>
            <Text style={styles.sectionLabel}>Invoice</Text>
            <View style={styles.chipWrap}>
              <FilterChip
                label="Entry only"
                active={!invoiceId}
                onPress={() => setInvoiceId("")}
              />
              {billableInvoices.map((invoice) => {
                const label = `${invoice.invoicePrefix ?? "#"}${invoice.invoiceNumber}`;
                return (
                  <FilterChip
                    key={invoice.id}
                    label={label}
                    active={invoiceId === invoice.id}
                    onPress={() => setInvoiceId(invoice.id)}
                  />
                );
              })}
            </View>
          </View>
        ) : null}

        {clientId ? (
          <View style={styles.setupSection}>
            <Pressable
              accessibilityRole="button"
              accessibilityState={{ expanded: optionsExpanded }}
              onPress={() => setOptionsExpanded((open) => !open)}
              style={({ pressed }) => [styles.optionsToggle, pressed && styles.optionsTogglePressed]}
            >
              <View style={styles.optionsToggleText}>
                <Text style={styles.optionsToggleLabel}>Rate & start time</Text>
                {!optionsExpanded ? (
                  <Text style={styles.optionsToggleSummary}>{optionsSummary}</Text>
                ) : null}
              </View>
              <Text style={styles.optionsChevron}>{optionsExpanded ? "−" : "+"}</Text>
            </Pressable>

            {optionsExpanded ? (
              <View style={styles.optionsBody}>
                <Input
                  label="Hourly rate"
                  value={rateText}
                  onChangeText={setRateText}
                  keyboardType="decimal-pad"
                  placeholder={
                    selectedClient?.defaultHourlyRate != null
                      ? String(selectedClient.defaultHourlyRate)
                      : "0"
                  }
                  error={clockInErrors.rate}
                />
                {selectedClient?.defaultHourlyRate != null && !rateText.trim() ? (
                  <Text style={styles.rateHint}>
                    Defaults to{" "}
                    {formatCurrency(selectedClient.defaultHourlyRate, rateCurrency)}/hr from client
                  </Text>
                ) : null}

                <Text style={[styles.sectionLabel, styles.sectionLabelInset]}>Start</Text>
                <View style={styles.chipWrap}>
                  <FilterChip
                    label="Now"
                    active={startMode === "now"}
                    onPress={() => selectStartMode("now")}
                  />
                  <FilterChip
                    label="Pick time"
                    active={startMode === "at"}
                    onPress={() => selectStartMode("at")}
                  />
                  <FilterChip
                    label="Time ago"
                    active={startMode === "ago"}
                    onPress={() => selectStartMode("ago")}
                  />
                </View>

                {startMode === "at" ? (
                  <DateTimeField
                    label="Started at"
                    value={startedAt}
                    maximumDate={new Date()}
                    onChange={(date) => {
                      setStartedAt(date);
                      setStartMode("at");
                    }}
                  />
                ) : null}

                {startMode === "ago" ? (
                  <View style={styles.agoBlock}>
                    <View style={styles.chipWrap}>
                      {AGO_PRESETS.map((preset) => (
                        <FilterChip
                          key={preset.label}
                          label={preset.label}
                          active={agoMinutes === preset.minutes}
                          onPress={() => selectAgoPreset(preset.minutes)}
                        />
                      ))}
                    </View>
                    <View style={styles.agoCustomRow}>
                      <Text style={[styles.agoCustomLabel, { color: colors.mutedForeground }]}>
                        Started
                      </Text>
                      <TextInput
                        value={agoMinutesText}
                        onChangeText={handleAgoMinutesChange}
                        keyboardType="number-pad"
                        style={[
                          styles.agoInput,
                          { color: colors.foreground, borderColor: colors.border },
                        ]}
                      />
                      <Text style={[styles.agoCustomLabel, { color: colors.mutedForeground }]}>
                        min ago
                      </Text>
                    </View>
                  </View>
                ) : null}

                {clockInErrors.start ? (
                  <Text style={styles.fieldError}>{clockInErrors.start}</Text>
                ) : null}
              </View>
            ) : null}
          </View>
        ) : null}

            <Button
              title={clockIn.isPending ? "Starting…" : "Start timer"}
              loading={clockIn.isPending}
              disabled={!canClockIn || clients.length === 0}
              showArrow={!clockIn.isPending}
              onPress={handleClockIn}
            />
          </>
        )}
      </GlassSurface>

      {todayEntries.length > 0 ? (
        <Card title="Today's entries">
          {todayEntries.map((entry) => {
            const invoiceLabel = entry.invoice
              ? `${entry.invoice.invoicePrefix ?? "#"}${entry.invoice.invoiceNumber}`
              : null;

            const row = (
              <>
                <View style={styles.entryMeta}>
                  <Text style={styles.entryTitle}>{formatRunningTimerLabel(entry.description)}</Text>
                  <Text style={styles.entrySub}>
                    {entry.client?.name ?? "No client"}
                    {invoiceLabel ? ` · ${invoiceLabel}` : " · not billed"}
                  </Text>
                </View>
                <Text style={styles.entryHours}>{entry.hours ?? "—"}h</Text>
              </>
            );

            if (!entry.invoice) {
              return (
                <View key={entry.id} style={styles.entryRow}>
                  {row}
                </View>
              );
            }

            return (
              <Pressable
                key={entry.id}
                accessibilityRole="button"
                accessibilityLabel={`View invoice ${invoiceLabel}`}
                onPress={() => router.push(`/(app)/invoices/${entry.invoice!.id}`)}
                style={({ pressed }) => [styles.entryRow, pressed && styles.entryRowPressed]}
              >
                {row}
              </Pressable>
            );
          })}
        </Card>
      ) : null}
    </TabScrollView>
  );
}

const createTimeClockStyles = (colors: ThemeColors, isDark: boolean) =>
  StyleSheet.create({
    scroll: {
      flex: 1,
    },
    runningCard: {
      borderColor: isDark ? "rgba(250, 250, 250, 0.12)" : "rgba(24, 24, 27, 0.12)",
      backgroundColor: isDark ? "rgba(250, 250, 250, 0.06)" : "rgba(24, 24, 27, 0.04)",
    },
    hero: {
      padding: spacing.lg,
      gap: spacing.sm,
    },
    heroRunning: {
      alignItems: "center",
    },
    heroHeader: {
      flexDirection: "row",
      alignItems: "center",
      justifyContent: "center",
      gap: spacing.sm,
    },
    pulseDot: {
      width: 10,
      height: 10,
      borderRadius: 5,
      backgroundColor: colors.primary,
    },
    heroLabelRunning: {
      fontSize: 14,
      fontFamily: fonts.bodyMedium,
      color: colors.primary,
    },
    timerValue: {
      fontSize: 56,
      lineHeight: 60,
      fontFamily: fonts.mono,
      color: colors.primary,
      fontVariant: ["tabular-nums"],
      textAlign: "center",
    },
    runningTitle: {
      fontSize: 18,
      fontFamily: fonts.bodyMedium,
      color: colors.foreground,
      textAlign: "center",
    },
    runningMeta: {
      fontSize: 14,
      fontFamily: fonts.body,
      color: colors.mutedForeground,
      textAlign: "center",
    },
    idleHint: {
      fontSize: 14,
      fontFamily: fonts.body,
      color: colors.mutedForeground,
      lineHeight: 20,
    },
    setupCard: {
      padding: spacing.lg,
      gap: spacing.lg,
    },
    cardTitle: {
      fontSize: 16,
      fontFamily: fonts.bodySemiBold,
      color: colors.foreground,
    },
    formSection: {
      gap: spacing.md,
    },
    titleField: {
      fontSize: 18,
      fontFamily: fonts.bodyMedium,
      minHeight: 48,
      paddingVertical: spacing.xs,
    },
    setupSection: {
      gap: spacing.sm,
      paddingTop: spacing.lg,
    },
    sectionLabel: {
      fontSize: 11,
      fontFamily: fonts.bodySemiBold,
      color: colors.mutedForeground,
      textTransform: "uppercase",
      letterSpacing: 0.6,
    },
    sectionLabelInset: {
      marginTop: spacing.sm,
    },
    chipWrap: {
      flexDirection: "row",
      flexWrap: "wrap",
      gap: spacing.sm,
    },
    moreClientsWrap: {
      paddingTop: spacing.xs,
    },
    emptyClients: {
      fontSize: 14,
      fontFamily: fonts.body,
      color: colors.mutedForeground,
    },
    fieldError: {
      fontSize: 12,
      fontFamily: fonts.body,
      color: colors.destructive,
    },
    optionsToggle: {
      flexDirection: "row",
      alignItems: "center",
      justifyContent: "space-between",
      gap: spacing.md,
      paddingVertical: spacing.sm,
      borderTopWidth: StyleSheet.hairlineWidth,
      borderTopColor: colors.border,
    },
    optionsTogglePressed: {
      opacity: 0.7,
    },
    optionsToggleText: {
      flex: 1,
      gap: 2,
    },
    optionsToggleLabel: {
      fontSize: 14,
      fontFamily: fonts.bodySemiBold,
      color: colors.foreground,
    },
    optionsToggleSummary: {
      fontSize: 12,
      fontFamily: fonts.body,
      color: colors.mutedForeground,
    },
    optionsChevron: {
      fontSize: 20,
      lineHeight: 22,
      fontFamily: fonts.bodyMedium,
      color: colors.mutedForeground,
    },
    optionsBody: {
      gap: spacing.md,
      paddingBottom: spacing.xs,
    },
    rateHint: {
      fontSize: 12,
      fontFamily: fonts.body,
      color: colors.mutedForeground,
    },
    agoBlock: {
      gap: spacing.sm,
    },
    agoCustomRow: {
      flexDirection: "row",
      alignItems: "center",
      gap: spacing.sm,
    },
    agoCustomLabel: {
      fontSize: 14,
      fontFamily: fonts.body,
    },
    agoInput: {
      minWidth: 56,
      fontSize: 16,
      fontFamily: fonts.bodySemiBold,
      borderBottomWidth: StyleSheet.hairlineWidth,
      paddingVertical: 4,
      textAlign: "center",
    },
    entryRow: {
      flexDirection: "row",
      justifyContent: "space-between",
      gap: spacing.md,
      paddingVertical: spacing.sm,
      borderTopWidth: 1,
      borderTopColor: colors.border,
    },
    entryRowPressed: {
      opacity: 0.65,
    },
    entryMeta: {
      flex: 1,
      gap: 2,
    },
    entryTitle: {
      fontFamily: fonts.bodySemiBold,
      color: colors.foreground,
      fontSize: 14,
    },
    entrySub: {
      fontFamily: fonts.body,
      color: colors.mutedForeground,
      fontSize: 12,
    },
    entryHours: {
      fontFamily: fonts.bodySemiBold,
      color: colors.foreground,
      fontSize: 14,
    },
  });
