import { useState, useEffect, useCallback } from 'react';
import apiService from '../services/apiService';
import { ApiError } from '../services/apiService';

// Define interfaces locally to avoid import issues
export interface UserDetails {
  user_id: string;
  full_name: string;
  email: string;
  user_image?: string;
  roles: string[];
  permissions: Record<string, {
    read: boolean;
    write: boolean;
    create: boolean;
    delete: boolean;
  }>;
  last_login?: string;
  enabled: boolean;
  creation: string;
  modified: string;
  language: string;
}

interface DocTypeRecord {
  name: string;
  creation: string;
  modified: string;
  modified_by: string;
  owner: string;
  docstatus: number;
  [key: string]: any;
}

export interface DocTypeRecordsResponse {
  records: DocTypeRecord[];
  total_count: number;
  limit: number;
  offset: number;
  has_more: boolean;
  doctype: string;
}

export interface DashboardStats {
  total_users: number;
  total_customers: number;
  total_items: number;
  total_orders: number;
  recent_activities: RecentActivity[];
}

export interface NumberCards {
  total_assets: number;
  work_orders_open: number;
  work_orders_in_progress: number;
  work_orders_completed: number;
  work_orders_closed: number;
}

interface RecentActivity {
  type: string;
  name: string;
  title: string;
  creation: string;
}

interface KycRecord {
  name: string;
  kyc_status: string;
  kyc_type: string;
  creation: string;
  modified: string;
}

export interface KycDetailsResponse {
  records: KycRecord[];
  summary: {
    total: number;
    pending: number;
    approved: number;
  };
}

// Generic API hook
export function useApi<T>(
  apiCall: () => Promise<T>,
  dependencies: any[] = []
) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  const fetchData = useCallback(async () => {
    try {
      setLoading(true);
      setError(null);
      const result = await apiCall();
      setData(result);
    } catch (err) {
      if (err instanceof ApiError) {
        setError(err.message);
      } else {
        setError(err instanceof Error ? err.message : 'Unknown error');
      }
    } finally {
      setLoading(false);
    }
  }, dependencies);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const refetch = useCallback(() => {
    fetchData();
  }, [fetchData]);

  return { data, loading, error, refetch };
}

// Specific API hooks
export function useUserDetails(userId?: string) {
  return useApi(
    () => apiService.getUserDetails(userId),
    [userId]
  );
}

export function useDashboardStats() {
  return useApi(() => apiService.getDashboardStats());
}

export function useNumberCards(filters?: Record<string, string>) {
  return useApi(
    () => apiService.getNumberCards(filters),
    [JSON.stringify(filters || {})]
  );
}

export function useDashboardChart(chartName: string, filters?: Record<string, any>) {
  return useApi(
    () => apiService.getDashboardChartData(chartName, filters),
    [chartName, JSON.stringify(filters || {})]
  );
}

export function useChartsList(publicOnly: boolean = true) {
  return useApi(() => apiService.listDashboardCharts(publicOnly), [publicOnly]);
}

export function useKycDetails() {
  return useApi(() => apiService.getKycDetails());
}

export function useDoctypeRecords(
  doctype: string,
  filters?: Record<string, any>,
  fields?: string[],
  limit: number = 20,
  offset: number = 0
) {
  return useApi(
    () => apiService.getDoctypeRecords(doctype, filters, fields, limit, offset),
    [doctype, JSON.stringify(filters), JSON.stringify(fields), limit, offset]
  );
}

// Authentication hook
export function useAuth() {
  const [isAuthenticated, setIsAuthenticated] = useState<boolean>(
    apiService.isAuthenticated()
  );

  const login = async (credentials: { email: string; password: string }) => {
    try {
      const response = await apiService.login(credentials);
      
      // Check if we have any valid response data
      if (response && response.message) {
        // Set session ID if available
        if (response.message.sid) {
          apiService.setSessionId(response.message.sid);
        }
        
        setIsAuthenticated(true);
        return response;
      }
      
      throw new Error('Login failed');
    } catch (error) {
      setIsAuthenticated(false);
      throw error;
    }
  };

  const logout = async () => {
    try {
      await apiService.logout();
    } finally {
      apiService.setSessionId('');
      setIsAuthenticated(false);
    }
  };

  return {
    isAuthenticated,
    login,
    logout
  };
}
