import { useState, useCallback } from 'react';
import type {
  ArticleDTO,
  CreateArticleRequest,
  UpdateArticleRequest,
  AddSalesUnitRequest,
  UpdateSalesUnitPriceRequest,
} from '@effigenix/api-client';
import { client } from '../utils/api-client.js';

interface ArticlesState {
  articles: ArticleDTO[];
  loading: boolean;
  error: string | null;
}

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

export function useArticles() {
  const [state, setState] = useState<ArticlesState>({
    articles: [],
    loading: false,
    error: null,
  });

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

  const createArticle = useCallback(async (request: CreateArticleRequest) => {
    setState((s) => ({ ...s, loading: true, error: null }));
    try {
      const article = await client.articles.create(request);
      setState((s) => ({ articles: [...s.articles, article], loading: false, error: null }));
      return article;
    } catch (err) {
      setState((s) => ({ ...s, loading: false, error: errorMessage(err) }));
      return null;
    }
  }, []);

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

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

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

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

  const removeSalesUnit = useCallback(async (articleId: string, salesUnitId: string) => {
    try {
      const updated = await client.articles.removeSalesUnit(articleId, salesUnitId);
      setState((s) => ({
        ...s,
        articles: s.articles.map((a) => (a.id === articleId ? updated : a)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const updateSalesUnitPrice = useCallback(
    async (articleId: string, salesUnitId: string, request: UpdateSalesUnitPriceRequest) => {
      try {
        const updated = await client.articles.updateSalesUnitPrice(articleId, salesUnitId, request);
        setState((s) => ({
          ...s,
          articles: s.articles.map((a) => (a.id === articleId ? updated : a)),
        }));
        return updated;
      } catch (err) {
        setState((s) => ({ ...s, error: errorMessage(err) }));
        return null;
      }
    },
    [],
  );

  const assignSupplier = useCallback(async (articleId: string, supplierId: string) => {
    try {
      const updated = await client.articles.assignSupplier(articleId, supplierId);
      setState((s) => ({
        ...s,
        articles: s.articles.map((a) => (a.id === articleId ? updated : a)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

  const removeSupplier = useCallback(async (articleId: string, supplierId: string) => {
    try {
      const updated = await client.articles.removeSupplier(articleId, supplierId);
      setState((s) => ({
        ...s,
        articles: s.articles.map((a) => (a.id === articleId ? updated : a)),
      }));
      return updated;
    } catch (err) {
      setState((s) => ({ ...s, error: errorMessage(err) }));
      return null;
    }
  }, []);

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

  return {
    ...state,
    fetchArticles,
    createArticle,
    updateArticle,
    activateArticle,
    deactivateArticle,
    addSalesUnit,
    removeSalesUnit,
    updateSalesUnitPrice,
    assignSupplier,
    removeSupplier,
    clearError,
  };
}
