import { useState, useCallback, useEffect, useMemo } from 'react';
import { useSnackbar } from '@/shared/components/snackbar';
import { useRouter } from '@/hooks';
import { useBoolean } from '@/hooks';
import { useTable } from '@/shared/components/table';
import { 
  deleteInvoice, 
  getGroupWithAddress, 
  getInvoicesByAgencyId, 
  getPaymentModes 
} from '@/shared/api/invoice';
import { getUserByEmail } from '@/shared/api/user';
import { paths } from '@/routes/paths';
import { applyFilter } from '../utils/invoice-filter';
import { getComparator } from '@/shared/components/table';
import { IInvoice, IInvoiceTableFilters, IInvoiceTableFilterValue } from '@/shared/types/invoice';
import { endpoints } from "@/utils/axios";
import { isAfter } from '@/utils/format-time';


const defaultFilters: IInvoiceTableFilters = {
  name: '',
  paymentMode: [],
  status: 'all',
  startDate: null,
  endDate: null,
};

export function useInvoiceList() {
  // States
  const [tableData, setTableData] = useState<IInvoice[]>([]);
  const [filters, setFilters] = useState(defaultFilters);
  const [paymentModeOptions, setPaymentModeOptions] = useState<string[]>([]);
  const [page, setPage] = useState(0);
  const [rowsPerPage, setRowsPerPage] = useState(5);
  const [agencyId, setAgencyId] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  // Hooks
  const { enqueueSnackbar } = useSnackbar();
  const router = useRouter();
  const table = useTable({ defaultOrderBy: 'createDate' });
  const confirm = useBoolean();
  const view = useBoolean();

  const dateError = isAfter(filters.startDate, filters.endDate);

  // Fetch Functions
  const fetchUserAgencyId = async () => {
    try {
      const storedAgencyId = localStorage.getItem('selectedAgency');
      
      if (!storedAgencyId) {
        throw new Error('No agency ID found');
      }

      setAgencyId(storedAgencyId);
    } catch (error) {
      console.error('Error getting agency ID:', error);
    
    }
  };

  const fetchInvoices = async (currentAgencyId: number) => {
    try {
      const invoices = await getInvoicesByAgencyId(currentAgencyId);
      
      if (Array.isArray(invoices)) {
        setTableData(invoices);
      } else {
        throw new Error('Invalid response format');
      }
    } catch (error) {
      console.error('Error fetching invoices:', error);
      
    }
  };

  const fetchPaymentModes = async () => {
    try {
      const paymentModes = await getPaymentModes();
      setPaymentModeOptions(paymentModes.map((mode: any) => mode.name));
    } catch (error) {
      console.error('Error fetching payment modes:', error);
  
    }
  };

  // Effects
  useEffect(() => {
    const initializeData = async () => {
      setIsLoading(true);
      await fetchUserAgencyId();
      setIsLoading(false);
    };

    initializeData();
  }, []);

  useEffect(() => {
    if (agencyId !== null) {
      const loadData = async () => {
        await Promise.all([
          fetchInvoices(Number(agencyId)),
          fetchPaymentModes()
        ]);
      };
      loadData();
    }
  }, [agencyId]);

  // Memoized Values
  const dataFiltered = useMemo(
    () => applyFilter({
      inputData: tableData,
      comparator: getComparator(table.order, table.orderBy),
      filters,
      dateError,
    }),
    [tableData, table.order, table.orderBy, filters, dateError]
  );

  const dataInPage = useMemo(
    () => dataFiltered.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage),
    [dataFiltered, page, rowsPerPage]
  );

  // Handlers
  const handleFilters = useCallback(
    (name: string, value: IInvoiceTableFilterValue) => {
      table.onResetPage();
      setFilters((prevState) => ({
        ...prevState,
        [name]: value,
      }));
    },
    [table]
  );

  const handleDeleteRow = useCallback(
    async (id: string) => {
      try {
        await deleteInvoice(id);
        setTableData((prevData) => prevData.filter((row) => row.id !== id));
        
        enqueueSnackbar('Invoice deleted successfully!', { variant: 'success' });
        table.onUpdatePageDeleteRow(dataInPage.length);
      } catch (error) {
        console.error('Error deleting invoice:', error);
        enqueueSnackbar('Failed to delete invoice', { variant: 'error' });
      }
    },
    [dataInPage.length, enqueueSnackbar, table]
  );

  const handleDeleteRows = useCallback(
    async () => {
      try {
        await fetch(endpoints.invoice.delete_list, {
          method: 'DELETE',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(table.selected),
        });
        
        setTableData((prevData) => prevData.filter((row) => !table.selected.includes(row.id)));
        
        table.onUpdatePageDeleteRows({
          totalRowsInPage: dataInPage.length,
          totalRowsFiltered: dataFiltered.length,
        });
        
        enqueueSnackbar('Delete success!', { variant: 'success' });
      } catch (error) {
        console.error('Error deleting multiple invoices:', error);
        enqueueSnackbar('Failed to delete invoices', { variant: 'error' });
      }
    },
    [dataFiltered.length, dataInPage.length, enqueueSnackbar, table]
  );

  const handleEditRow = useCallback(
    (id: string) => {
      router.push(paths.dashboard.invoice.edit(id));
    },
    [router]
  );

  const handleViewRow = useCallback(
    (id: string) => {
      router.push(paths.dashboard.invoice.details(id));
    },
    [router]
  );

  return {
    // Data
    tableData,
    dataFiltered,
    dataInPage,
    paymentModeOptions,
    
    // States
    filters,
    isLoading,
    dateError,
    page,
    rowsPerPage,
    
    // Handlers
    handleFilters,
    handleDeleteRow,
    handleDeleteRows,
    handleEditRow,
    handleViewRow,
    setPage,
    setRowsPerPage,
    
    // Utils
    table,
    confirm,
    view,
  };
}