import { useState, useCallback } from 'react';
import type { BatchSummaryDTO, BatchDTO, PlanBatchRequest, BatchStatus } from '@effigenix/api-client';
import { client } from '../utils/api-client.js';

interface BatchesState {
  batches: BatchSummaryDTO[];
  batch: BatchDTO | null;
  loading: boolean;
  error: string | null;
}

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

export function useBatches() {
  const [state, setState] = useState<BatchesState>({
    batches: [],
    batch: null,
    loading: false,
    error: null,
  });

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

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

  const planBatch = useCallback(async (request: PlanBatchRequest) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const batch = await client.batches.plan(request);
      setState((s) => ({ ...s, loading: false, error: null }));
      return batch;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

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

  const recordConsumption = useCallback(async (id: string, request: Parameters<typeof client.batches.recordConsumption>[1]) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      await client.batches.recordConsumption(id, request);
      const batch = await client.batches.getById(id);
      setState((s) => ({ ...s, batch, loading: false, error: null }));
      return true;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return false;
    }
  }, []);

  const completeBatch = useCallback(async (id: string, request: Parameters<typeof client.batches.complete>[1]) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const batch = await client.batches.complete(id, request);
      setState((s) => ({ ...s, batch, loading: false, error: null }));
      return batch;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

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

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

  return {
    ...state,
    fetchBatches,
    fetchBatch,
    planBatch,
    startBatch,
    recordConsumption,
    completeBatch,
    cancelBatch,
    clearError,
  };
}
