import { useEffect, useState } from "react";
import {
  Alert,
  KeyboardAvoidingView,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  View,
} from "react-native";

import { Button } from "@/components/ui/Button";
import { Card } from "@/components/ui/Card";
import { Input } from "@/components/ui/Input";
import { fonts, spacing } from "@/constants/theme";
import type { ThemeColors } from "@/lib/theme-palette";
import { useThemedStyles } from "@/lib/use-themed-styles";
import { isRequiredString, parseNonNegativeNumber } from "@/lib/form-validation";
import { api } from "@/lib/trpc";

export type ClientFormValues = {
  name: string;
  email: string;
  phone: string;
  addressLine1: string;
  addressLine2: string;
  city: string;
  state: string;
  postalCode: string;
  country: string;
  defaultHourlyRate: string;
  currency: string;
};

const emptyValues: ClientFormValues = {
  name: "",
  email: "",
  phone: "",
  addressLine1: "",
  addressLine2: "",
  city: "",
  state: "",
  postalCode: "",
  country: "United States",
  defaultHourlyRate: "",
  currency: "USD",
};

type ClientFormProps = {
  mode: "create" | "edit";
  clientId?: string;
  scrollPadding: number;
  onSaved: () => void;
  onDeleted?: () => void;
};

export function ClientForm({
  mode,
  clientId,
  scrollPadding,
  onSaved,
  onDeleted,
}: ClientFormProps) {
  const styles = useThemedStyles(createClientFormStyles);
  const utils = api.useUtils();

  const clientQuery = api.clients.getById.useQuery(
    { id: clientId ?? "" },
    { enabled: mode === "edit" && Boolean(clientId) },
  );

  const [values, setValues] = useState<ClientFormValues>(emptyValues);
  const [fieldError, setFieldError] = useState<string | null>(null);

  useEffect(() => {
    const client = clientQuery.data;
    if (!client) return;
    setValues({
      name: client.name,
      email: client.email ?? "",
      phone: client.phone ?? "",
      addressLine1: client.addressLine1 ?? "",
      addressLine2: client.addressLine2 ?? "",
      city: client.city ?? "",
      state: client.state ?? "",
      postalCode: client.postalCode ?? "",
      country: client.country ?? "United States",
      defaultHourlyRate:
        client.defaultHourlyRate != null ? String(client.defaultHourlyRate) : "",
      currency: client.currency ?? "USD",
    });
  }, [clientQuery.data]);

  const createClient = api.clients.create.useMutation({
    onSuccess: () => {
      void utils.clients.getAll.invalidate();
      void utils.dashboard.getStats.invalidate();
      onSaved();
    },
    onError: (err) => setFieldError(err.message),
  });

  const updateClient = api.clients.update.useMutation({
    onSuccess: () => {
      void utils.clients.getAll.invalidate();
      if (clientId) void utils.clients.getById.invalidate({ id: clientId });
      void utils.dashboard.getStats.invalidate();
      onSaved();
    },
    onError: (err) => setFieldError(err.message),
  });

  const deleteClient = api.clients.delete.useMutation({
    onSuccess: () => {
      void utils.clients.getAll.invalidate();
      void utils.dashboard.getStats.invalidate();
      onDeleted?.();
    },
    onError: (err) => Alert.alert("Could not delete client", err.message),
  });

  function patch(field: keyof ClientFormValues, value: string) {
    setValues((prev) => ({ ...prev, [field]: value }));
    setFieldError(null);
  }

  function handleSave() {
    if (!canSave) return;

    const rate = values.defaultHourlyRate.trim()
      ? Number(values.defaultHourlyRate)
      : undefined;
    if (rate !== undefined && (Number.isNaN(rate) || rate < 0)) {
      setFieldError("Hourly rate must be a valid number");
      return;
    }

    const payload = {
      name: values.name.trim(),
      email: values.email.trim(),
      phone: values.phone.trim(),
      addressLine1: values.addressLine1.trim(),
      addressLine2: values.addressLine2.trim(),
      city: values.city.trim(),
      state: values.state.trim(),
      postalCode: values.postalCode.trim(),
      country: values.country.trim() || "United States",
      defaultHourlyRate: rate,
      currency: values.currency.trim() || "USD",
    };

    if (mode === "create") {
      createClient.mutate(payload);
      return;
    }

    if (!clientId) return;
    updateClient.mutate({ id: clientId, ...payload });
  }

  function confirmDelete() {
    if (!clientId) return;
    Alert.alert(
      "Delete client",
      "This cannot be undone. Clients with invoices cannot be deleted.",
      [
        { text: "Cancel", style: "cancel" },
        {
          text: "Delete",
          style: "destructive",
          onPress: () => deleteClient.mutate({ id: clientId }),
        },
      ],
    );
  }

  const saving = createClient.isPending || updateClient.isPending;

  const nameError = values.name.trim() ? undefined : "Name is required";
  const rateError =
    values.defaultHourlyRate.trim() && parseNonNegativeNumber(values.defaultHourlyRate) === null
      ? "Hourly rate must be a valid number"
      : undefined;
  const canSave = isRequiredString(values.name) && !rateError;

  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === "ios" ? "padding" : undefined}
      style={styles.flex}
    >
      <ScrollView
        contentContainerStyle={[styles.container, { paddingBottom: scrollPadding }]}
        contentInsetAdjustmentBehavior={Platform.OS === "ios" ? "automatic" : undefined}
        scrollIndicatorInsets={{ bottom: scrollPadding }}
        keyboardShouldPersistTaps="handled"
      >
        <Card title="Contact">
          <Input
            label="Name"
            value={values.name}
            onChangeText={(v) => patch("name", v)}
            required
            error={nameError}
          />
          <Input
            label="Email"
            value={values.email}
            onChangeText={(v) => patch("email", v)}
            keyboardType="email-address"
            autoCapitalize="none"
          />
          <Input
            label="Phone"
            value={values.phone}
            onChangeText={(v) => patch("phone", v)}
            keyboardType="phone-pad"
          />
        </Card>

        <Card title="Address">
          <Input
            label="Address line 1"
            value={values.addressLine1}
            onChangeText={(v) => patch("addressLine1", v)}
          />
          <Input
            label="Address line 2"
            value={values.addressLine2}
            onChangeText={(v) => patch("addressLine2", v)}
          />
          <Input label="City" value={values.city} onChangeText={(v) => patch("city", v)} />
          <Input label="State" value={values.state} onChangeText={(v) => patch("state", v)} />
          <Input
            label="Postal code"
            value={values.postalCode}
            onChangeText={(v) => patch("postalCode", v)}
          />
          <Input
            label="Country"
            value={values.country}
            onChangeText={(v) => patch("country", v)}
          />
        </Card>

        <Card title="Billing">
          <Input
            label="Default hourly rate"
            value={values.defaultHourlyRate}
            onChangeText={(v) => patch("defaultHourlyRate", v)}
            keyboardType="decimal-pad"
            placeholder="Optional"
            error={rateError}
          />
          <Input
            label="Currency"
            value={values.currency}
            onChangeText={(v) => patch("currency", v.toUpperCase())}
            autoCapitalize="characters"
            maxLength={3}
          />
        </Card>

        {fieldError ? <Text style={styles.error}>{fieldError}</Text> : null}

        <View style={styles.actions}>
          <Button
            title={mode === "create" ? "Create client" : "Save changes"}
            loading={saving}
            disabled={!canSave}
            onPress={handleSave}
          />
          {mode === "edit" ? (
            <Button
              title="Delete client"
              variant="danger"
              loading={deleteClient.isPending}
              onPress={confirmDelete}
            />
          ) : null}
        </View>
      </ScrollView>
    </KeyboardAvoidingView>
  );
}

const createClientFormStyles = (colors: ThemeColors, _isDark: boolean) =>
  StyleSheet.create({
    flex: { flex: 1 },
    container: {
      padding: spacing.md,
      gap: spacing.md,
    },
    actions: {
      gap: spacing.sm,
    },
    error: {
      color: colors.destructive,
      fontFamily: fonts.body,
      fontSize: 14,
    },
  });
