import { useState, useCallback } from 'react';
import type {
  CustomerDTO,
  CustomerPreference,
  CreateCustomerRequest,
  UpdateCustomerRequest,
  AddDeliveryAddressRequest,
} from '@effigenix/api-client';
import { client } from '../utils/api-client.js';

interface CustomersState {
  customers: CustomerDTO[];
  loading: boolean;
  error: string | null;
}

function errorMessage(err: unknown): string {
  return err instanceof Error ? err.message : 'Unbekannter Fehler';
}

export function useCustomers() {
  const [state, setState] = useState<CustomersState>({
    customers: [],
    loading: false,
    error: null,
  });

  const fetchCustomers = useCallback(async () => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const customers = await client.customers.list();
      setState({ customers, loading: false, error: null });
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
    }
  }, []);

  const createCustomer = useCallback(async (request: CreateCustomerRequest) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const customer = await client.customers.create(request);
      setState((s) => ({ customers: [...s.customers, customer], loading: false, error: null }));
      return customer;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const updateCustomer = useCallback(async (id: string, request: UpdateCustomerRequest) => {
    try {
      const updated = await client.customers.update(id, request);
      setState((s) => ({
        ...s,
        customers: s.customers.map((c) => (c.id === id ? updated : c)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const activateCustomer = useCallback(async (id: string) => {
    try {
      const updated = await client.customers.activate(id);
      setState((s) => ({
        ...s,
        customers: s.customers.map((c) => (c.id === id ? updated : c)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const deactivateCustomer = useCallback(async (id: string) => {
    try {
      const updated = await client.customers.deactivate(id);
      setState((s) => ({
        ...s,
        customers: s.customers.map((c) => (c.id === id ? updated : c)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const addDeliveryAddress = useCallback(async (id: string, request: AddDeliveryAddressRequest) => {
    try {
      const updated = await client.customers.addDeliveryAddress(id, request);
      setState((s) => ({
        ...s,
        customers: s.customers.map((c) => (c.id === id ? updated : c)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const removeDeliveryAddress = useCallback(async (id: string, label: string) => {
    try {
      const updated = await client.customers.removeDeliveryAddress(id, label);
      setState((s) => ({
        ...s,
        customers: s.customers.map((c) => (c.id === id ? updated : c)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const setPreferences = useCallback(async (id: string, preferences: CustomerPreference[]) => {
    try {
      const updated = await client.customers.setPreferences(id, preferences);
      setState((s) => ({
        ...s,
        customers: s.customers.map((c) => (c.id === id ? updated : c)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const clearError = useCallback(() => {
    setState((s) => ({ ...s, error: null }));
  }, []);

  return {
    ...state,
    fetchCustomers,
    createCustomer,
    updateCustomer,
    activateCustomer,
    deactivateCustomer,
    addDeliveryAddress,
    removeDeliveryAddress,
    setPreferences,
    clearError,
  };
}
