import { useEffect, useState } from "react";
import {
  Alert,
  KeyboardAvoidingView,
  Platform,
  ScrollView,
  StyleSheet,
  Switch,
  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 { useAppTheme } from "@/contexts/ThemeContext";
import type { ThemeColors } from "@/lib/theme-palette";
import { useThemedStyles } from "@/lib/use-themed-styles";
import { isRequiredString } from "@/lib/form-validation";
import { api } from "@/lib/trpc";

type BusinessFormValues = {
  name: string;
  nickname: string;
  email: string;
  phone: string;
  addressLine1: string;
  addressLine2: string;
  city: string;
  state: string;
  postalCode: string;
  country: string;
  website: string;
  taxId: string;
  isDefault: boolean;
};

const emptyValues: BusinessFormValues = {
  name: "",
  nickname: "",
  email: "",
  phone: "",
  addressLine1: "",
  addressLine2: "",
  city: "",
  state: "",
  postalCode: "",
  country: "United States",
  website: "",
  taxId: "",
  isDefault: false,
};

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

export function BusinessForm({
  mode,
  businessId,
  scrollPadding,
  onSaved,
  onDeleted,
}: BusinessFormProps) {
  const { colors } = useAppTheme();
  const styles = useThemedStyles(createBusinessFormStyles);
  const utils = api.useUtils();

  const businessQuery = api.businesses.getById.useQuery(
    { id: businessId ?? "" },
    { enabled: mode === "edit" && Boolean(businessId) },
  );

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

  const switchProps = {
    trackColor: { false: colors.switchTrackOff, true: colors.switchTrackOn },
    thumbColor: Platform.OS === "android" ? colors.switchThumb : undefined,
    ios_backgroundColor: colors.switchIosBackground,
  };

  useEffect(() => {
    const business = businessQuery.data;
    if (!business) return;
    setValues({
      name: business.name,
      nickname: business.nickname ?? "",
      email: business.email ?? "",
      phone: business.phone ?? "",
      addressLine1: business.addressLine1 ?? "",
      addressLine2: business.addressLine2 ?? "",
      city: business.city ?? "",
      state: business.state ?? "",
      postalCode: business.postalCode ?? "",
      country: business.country ?? "United States",
      website: business.website ?? "",
      taxId: business.taxId ?? "",
      isDefault: business.isDefault ?? false,
    });
  }, [businessQuery.data]);

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

  const updateBusiness = api.businesses.update.useMutation({
    onSuccess: () => {
      void utils.businesses.getAll.invalidate();
      if (businessId) void utils.businesses.getById.invalidate({ id: businessId });
      onSaved();
    },
    onError: (err) => setFieldError(err.message),
  });

  const deleteBusiness = api.businesses.delete.useMutation({
    onSuccess: () => {
      void utils.businesses.getAll.invalidate();
      onDeleted?.();
    },
    onError: (err) => Alert.alert("Could not delete business", err.message),
  });

  function patch<K extends keyof BusinessFormValues>(field: K, value: BusinessFormValues[K]) {
    setValues((prev) => ({ ...prev, [field]: value }));
    setFieldError(null);
  }

  function buildPayload() {
    return {
      name: values.name.trim(),
      nickname: values.nickname.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",
      website: values.website.trim(),
      taxId: values.taxId.trim(),
      isDefault: values.isDefault,
    };
  }

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

    const payload = buildPayload();

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

    if (!businessId) return;
    updateBusiness.mutate({ id: businessId, ...payload });
  }

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

  const saving = createBusiness.isPending || updateBusiness.isPending;
  const nameError = values.name.trim() ? undefined : "Business name is required";
  const canSave = isRequiredString(values.name);

  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="Profile">
          <Input
            label="Name"
            value={values.name}
            onChangeText={(v) => patch("name", v)}
            required
            error={nameError}
          />
          <Input
            label="Nickname"
            value={values.nickname}
            onChangeText={(v) => patch("nickname", v)}
            placeholder="Optional short name"
          />
          <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"
          />
          <Input
            label="Website"
            value={values.website}
            onChangeText={(v) => patch("website", v)}
            autoCapitalize="none"
            keyboardType="url"
            placeholder="https://"
          />
          <Input
            label="Tax ID"
            value={values.taxId}
            onChangeText={(v) => patch("taxId", v)}
            placeholder="Optional"
          />
          <View style={styles.switchRow}>
            <View style={styles.switchCopy}>
              <Text style={[styles.switchLabel, { color: colors.foreground }]}>
                Default business
              </Text>
              <Text style={[styles.switchHint, { color: colors.mutedForeground }]}>
                Used for new invoices when none is selected
              </Text>
            </View>
            <Switch
              value={values.isDefault}
              onValueChange={(v) => patch("isDefault", v)}
              {...switchProps}
            />
          </View>
        </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>

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

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

const createBusinessFormStyles = (colors: ThemeColors, _isDark: boolean) =>
  StyleSheet.create({
    flex: { flex: 1 },
    container: {
      padding: spacing.md,
      gap: spacing.md,
    },
    switchRow: {
      flexDirection: "row",
      alignItems: "center",
      justifyContent: "space-between",
      gap: spacing.md,
      paddingTop: spacing.xs,
    },
    switchCopy: {
      flex: 1,
      gap: 2,
    },
    switchLabel: {
      fontFamily: fonts.bodyMedium,
      fontSize: 14,
    },
    switchHint: {
      fontFamily: fonts.body,
      fontSize: 12,
      lineHeight: 16,
    },
    actions: {
      gap: spacing.sm,
    },
    error: {
      color: colors.destructive,
      fontFamily: fonts.body,
      fontSize: 14,
    },
  });
