import { useState, useCallback } from 'react';
import type {
  InventoryCountDTO,
  CreateInventoryCountRequest,
  RecordCountItemRequest,
  InventoryCountFilter,
} from '@effigenix/api-client';
import { client } from '../utils/api-client.js';

interface InventoryCountsState {
  inventoryCounts: InventoryCountDTO[];
  inventoryCount: InventoryCountDTO | null;
  loading: boolean;
  error: string | null;
}

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

export function useInventoryCounts() {
  const [state, setState] = useState<InventoryCountsState>({
    inventoryCounts: [],
    inventoryCount: null,
    loading: false,
    error: null,
  });

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

  const fetchInventoryCount = useCallback(async (id: string) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const inventoryCount = await client.inventoryCounts.getById(id);
      setState((s) => ({ ...s, inventoryCount, loading: false, error: null }));
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
    }
  }, []);

  const createInventoryCount = useCallback(async (request: CreateInventoryCountRequest) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const inventoryCount = await client.inventoryCounts.create(request);
      setState((s) => ({ ...s, loading: false, error: null }));
      return inventoryCount;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const startInventoryCount = useCallback(async (id: string) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const inventoryCount = await client.inventoryCounts.start(id);
      setState((s) => ({ ...s, inventoryCount, loading: false, error: null }));
      return inventoryCount;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const recordCountItem = useCallback(async (countId: string, itemId: string, request: RecordCountItemRequest) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const inventoryCount = await client.inventoryCounts.recordItem(countId, itemId, request);
      setState((s) => ({ ...s, inventoryCount, loading: false, error: null }));
      return inventoryCount;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const completeInventoryCount = useCallback(async (id: string) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const inventoryCount = await client.inventoryCounts.complete(id);
      setState((s) => ({ ...s, inventoryCount, loading: false, error: null }));
      return inventoryCount;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const cancelInventoryCount = useCallback(async (id: string, reason: string) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const inventoryCount = await client.inventoryCounts.cancel(id, { reason });
      setState((s) => ({ ...s, inventoryCount, loading: false, error: null }));
      return inventoryCount;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

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

  return {
    ...state,
    fetchInventoryCounts,
    fetchInventoryCount,
    createInventoryCount,
    startInventoryCount,
    recordCountItem,
    completeInventoryCount,
    cancelInventoryCount,
    clearError,
  };
}
