import { Switch, StyleSheet, Text, View } from "react-native";

import { DateTimeField } from "@/components/ui/DateTimeField";
import { Input } from "@/components/ui/Input";
import { SelectField, type SelectOption } from "@/components/ui/SelectField";
import { fonts, spacing } from "@/constants/theme";
import { useAppTheme } from "@/contexts/ThemeContext";
import { EXPENSE_CATEGORIES } from "@/lib/expense-categories";

const NONE = "__none__";

export type ExpenseFormState = {
  description: string;
  amountText: string;
  date: Date;
  category: string;
  businessId: string;
  clientId: string;
  billable: boolean;
  reimbursable: boolean;
  taxDeductible: boolean;
  notes: string;
};

type ExpenseFormFieldsProps = {
  value: ExpenseFormState;
  businesses: Array<{ id: string; name: string; isDefault?: boolean | null }>;
  clients: Array<{ id: string; name: string }>;
  onChange: (value: ExpenseFormState) => void;
  notesLabel?: string;
  notesPlaceholder?: string;
};

export function defaultExpenseFormState(
  defaultBusinessId = "",
): ExpenseFormState {
  return {
    description: "",
    amountText: "",
    date: new Date(),
    category: "",
    businessId: defaultBusinessId,
    clientId: "",
    billable: false,
    reimbursable: false,
    taxDeductible: false,
    notes: "",
  };
}

export function ExpenseFormFields({
  value,
  businesses,
  clients,
  onChange,
  notesLabel = "Notes",
  notesPlaceholder = "Internal details or receipt OCR text",
}: ExpenseFormFieldsProps) {
  const { colors } = useAppTheme();

  const businessOptions: SelectOption[] = [
    { label: "Default business", value: NONE },
    ...businesses.map((business) => ({
      label: business.isDefault ? `${business.name} (default)` : business.name,
      value: business.id,
    })),
  ];
  const clientOptions: SelectOption[] = [
    { label: "No client", value: NONE },
    ...clients.map((client) => ({ label: client.name, value: client.id })),
  ];
  const categoryOptions: SelectOption[] = [
    { label: "No category", value: NONE },
    ...EXPENSE_CATEGORIES.map((category) => ({
      label: category,
      value: category,
    })),
  ];

  const setField = <K extends keyof ExpenseFormState>(
    field: K,
    nextValue: ExpenseFormState[K],
  ) => onChange({ ...value, [field]: nextValue });

  return (
    <View style={styles.stack}>
      <Input
        label="Description"
        required
        value={value.description}
        onChangeText={(text) => setField("description", text)}
        placeholder="e.g. Client lunch"
      />
      <Input
        label="Amount"
        required
        value={value.amountText}
        onChangeText={(text) => setField("amountText", text)}
        keyboardType="decimal-pad"
        placeholder="0.00"
      />
      <DateTimeField
        label="Date"
        value={value.date}
        onChange={(date) => setField("date", date)}
        mode="date"
      />
      <SelectField
        label="Category"
        placeholder="No category"
        value={value.category || NONE}
        options={categoryOptions}
        onValueChange={(next) =>
          setField("category", next === NONE ? "" : next)
        }
      />
      <SelectField
        label="Business"
        placeholder="Default business"
        value={value.businessId || NONE}
        options={businessOptions}
        onValueChange={(next) =>
          setField("businessId", next === NONE ? "" : next)
        }
      />
      <SelectField
        label="Client"
        placeholder="No client"
        value={value.clientId || NONE}
        options={clientOptions}
        onValueChange={(next) =>
          setField("clientId", next === NONE ? "" : next)
        }
      />

      <View style={styles.flags}>
        <FlagSwitch
          label="Billable"
          value={value.billable}
          onValueChange={(next) => setField("billable", next)}
        />
        <FlagSwitch
          label="Reimbursable"
          value={value.reimbursable}
          onValueChange={(next) => setField("reimbursable", next)}
        />
        <FlagSwitch
          label="Tax deductible"
          value={value.taxDeductible}
          onValueChange={(next) => setField("taxDeductible", next)}
        />
      </View>

      <Input
        label={notesLabel}
        value={value.notes}
        onChangeText={(text) => setField("notes", text)}
        placeholder={notesPlaceholder}
        multiline
        style={styles.notesInput}
      />
    </View>
  );

  function FlagSwitch({
    label,
    value: checked,
    onValueChange,
  }: {
    label: string;
    value: boolean;
    onValueChange: (value: boolean) => void;
  }) {
    return (
      <View style={[styles.flagRow, { borderColor: colors.borderGlass }]}>
        <Text style={[styles.flagLabel, { color: colors.foreground }]}>
          {label}
        </Text>
        <Switch
          value={checked}
          onValueChange={onValueChange}
          trackColor={{
            true: colors.switchTrackOn,
            false: colors.switchTrackOff,
          }}
          thumbColor={colors.switchThumb}
          ios_backgroundColor={colors.switchIosBackground}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  stack: {
    gap: spacing.md,
  },
  flags: {
    gap: spacing.sm,
  },
  flagRow: {
    minHeight: 48,
    borderWidth: 1,
    borderRadius: 12,
    paddingHorizontal: spacing.md,
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
  },
  flagLabel: {
    fontFamily: fonts.bodyMedium,
    fontSize: 14,
  },
  notesInput: {
    minHeight: 96,
    textAlignVertical: "top",
    paddingTop: spacing.md,
  },
});
