import { create } from 'zustand';
import api from './api';

export interface Item {
  id: number;
  uid: string;
  name: string;
  code: string;
  barcode: string;
  description: string;
  category_id: number;
  category_name?: string;
  unit: string;
  purchase_price: number;
  selling_price: number;
  reorder_level: number;
  supplier_id: number;
  supplier_name?: string;
  total_stock?: number;
  is_active: number;
}

export interface ItemCategory {
  id: number;
  uid: string;
  name: string;
  code: string;
  description: string;
  parent_id: number | null;
}

export interface Supplier {
  id: number;
  uid: string;
  name: string;
  code: string;
  contact_person: string;
  email: string;
  phone: string;
}

export interface StoreLocation {
  id: number;
  uid: string;
  name: string;
  code: string;
  is_warehouse: number;
}

export interface ItemStock {
  id: number;
  item_id: number;
  item_name?: string;
  store_id: number;
  store_name?: string;
  quantity: number;
  unit?: string;
}

export interface ItemIssue {
  id: number;
  uid: string;
  item_id: number;
  item_name?: string;
  issued_to_type: 'staff' | 'department' | 'student' | 'class';
  issued_to_id: number;
  quantity: number;
  purpose: string;
  issue_date: string;
  return_due_date: string;
  returned_date: string | null;
  returned_quantity: number;
  status: 'issued' | 'returned' | 'partially_returned' | 'damaged';
  issuer_name?: string;
}

interface InventoryState {
  items: Item[];
  categories: ItemCategory[];
  suppliers: Supplier[];
  locations: StoreLocation[];
  stock: ItemStock[];
  issues: ItemIssue[];
  loading: boolean;
  error: string | null;

  fetchItems: (filters?: any) => Promise<void>;
  createItem: (data: any) => Promise<void>;
  createCategory: (data: any) => Promise<any>;
  createSupplier: (data: any) => Promise<any>;
  fetchCategories: () => Promise<void>;
  fetchSuppliers: () => Promise<void>;
  fetchLocations: () => Promise<void>;
  fetchStock: (filters?: any) => Promise<void>;
  fetchIssues: (filters?: any) => Promise<void>;
  recordTransaction: (data: any) => Promise<void>;
  issueItem: (data: any) => Promise<void>;
  returnItem: (issueId: number, data: any) => Promise<void>;
}

export const useInventoryStore = create<InventoryState>((set) => ({
  items: [],
  categories: [],
  suppliers: [],
  locations: [],
  stock: [],
  issues: [],
  loading: false,
  error: null,

  fetchItems: async (filters) => {
    set({ loading: true });
    try {
      const res = await api.get('/inventory/items', { params: filters });
      set({ items: res.data, loading: false });
    } catch (err: any) {
      set({ error: err.message, loading: false });
    }
  },

  createItem: async (data) => {
    set({ loading: true });
    try {
      await api.post('/inventory/items', data);
      const res = await api.get('/inventory/items');
      set({ items: res.data, loading: false });
    } catch (err: any) {
      set({ error: err.message, loading: false });
    }
  },

  createCategory: async (data) => {
    set({ loading: true });
    try {
      const res = await api.post('/inventory/categories', data);
      const categoriesRes = await api.get('/inventory/categories');
      set({ categories: categoriesRes.data, loading: false });
      return res.data;
    } catch (err: any) {
      set({ error: err.message, loading: false });
      throw err;
    }
  },

  createSupplier: async (data) => {
    set({ loading: true });
    try {
      const res = await api.post('/inventory/suppliers', data);
      const suppliersRes = await api.get('/inventory/suppliers');
      set({ suppliers: suppliersRes.data, loading: false });
      return res.data;
    } catch (err: any) {
      set({ error: err.message, loading: false });
      throw err;
    }
  },

  fetchCategories: async () => {
    try {
      const res = await api.get('/inventory/categories');
      set({ categories: res.data });
    } catch (err: any) {
      set({ error: err.message });
    }
  },

  fetchSuppliers: async () => {
    try {
      const res = await api.get('/inventory/suppliers');
      set({ suppliers: res.data });
    } catch (err: any) {
      set({ error: err.message });
    }
  },

  fetchLocations: async () => {
    try {
      const res = await api.get('/inventory/locations');
      set({ locations: res.data });
    } catch (err: any) {
      set({ error: err.message });
    }
  },

  fetchStock: async (filters) => {
    try {
      const res = await api.get('/inventory/stock', { params: filters });
      set({ stock: res.data });
    } catch (err: any) {
      set({ error: err.message });
    }
  },

  fetchIssues: async (filters) => {
    set({ loading: true });
    try {
      const res = await api.get('/inventory/issues', { params: filters });
      set({ issues: res.data, loading: false });
    } catch (err: any) {
      set({ error: err.message, loading: false });
    }
  },

  recordTransaction: async (data) => {
    set({ loading: true });
    try {
      await api.post('/inventory/transactions', data);
      const resItems = await api.get('/inventory/items');
      const resStock = await api.get('/inventory/stock');
      set({ items: resItems.data, stock: resStock.data, loading: false });
    } catch (err: any) {
      set({ error: err.message, loading: false });
    }
  },

  issueItem: async (data) => {
    set({ loading: true });
    try {
      await api.post('/inventory/issues', data);
      const resItems = await api.get('/inventory/items');
      const resIssues = await api.get('/inventory/issues');
      set({ items: resItems.data, issues: resIssues.data, loading: false });
    } catch (err: any) {
      set({ error: err.message, loading: false });
    }
  },

  returnItem: async (issueId, data) => {
    set({ loading: true });
    try {
      await api.post(`/inventory/issues/${issueId}/return`, data);
      const resItems = await api.get('/inventory/items');
      const resIssues = await api.get('/inventory/issues');
      set({ items: resItems.data, issues: resIssues.data, loading: false });
    } catch (err: any) {
      set({ error: err.message, loading: false });
    }
  },
}));
