import { useState, useEffect, useCallback, useMemo } from "react";
import { useDebounce } from "../useDebounce";
import useSubscriptionPlanService from "./useSubscriptionPlanService";
import {
  type SubscriptionPlan,
  type SubscriptionPlanFilters,
} from "../../services/subscriptionPlanService";

interface UseSubscriptionPlanState {
  subscriptionPlans: SubscriptionPlan[];
  total: number;
  currentPage: number;
  totalPages: number;
  itemsPerPage: number;
  searchTerm: string;
  companyId: string;
  fromDate: string;
  toDate: string;
  statusFilter: "all" | "active" | "expired" | "upcoming";
  sortField: string | null;
  sortDirection: "ASC" | "DESC";
  loading: boolean;
  error: string | null;
}

interface UseSubscriptionPlanActions {
  setSearchTerm: (term: string) => void;
  setCompanyId: (id: string) => void;
  setFromDate: (date: string) => void;
  setToDate: (date: string) => void;
  setStatusFilter: (filter: "all" | "active" | "expired" | "upcoming") => void;
  setSortField: (field: string | null) => void;
  setSortDirection: (direction: "ASC" | "DESC") => void;
  setCurrentPage: (page: number) => void;
  setItemsPerPage: (items: number) => void;
  clearFilters: () => void;
  refreshData: () => Promise<void>;
}

const INITIAL_STATE: UseSubscriptionPlanState = {
  subscriptionPlans: [],
  total: 0,
  currentPage: 1,
  totalPages: 0,
  itemsPerPage: 100,
  searchTerm: "",
  companyId: "",
  fromDate: "",
  toDate: "",
  statusFilter: "all",
  sortField: "created_at",
  sortDirection: "DESC",
  loading: false,
  error: null,
};

function useSubscriptionPlan() {
  const [state, setState] = useState<UseSubscriptionPlanState>(INITIAL_STATE);
  const service = useSubscriptionPlanService();

  // Debounce search term with 500ms delay
  const debouncedSearchTerm = useDebounce(state.searchTerm, 500);

  // Memoize filters to prevent unnecessary API calls
  const filters = useMemo<SubscriptionPlanFilters>(() => {
    const filters: SubscriptionPlanFilters = {
      search: debouncedSearchTerm,
      page: state.currentPage,
      limit: state.itemsPerPage,
    };

    if (state.companyId) {
      filters.company_id = state.companyId;
    }

    // Only pass date range when valid (fromDate <= toDate)
    const fromDate = state.fromDate;
    const toDate = state.toDate;
    const isDateRangeValid =
      !fromDate ||
      !toDate ||
      fromDate <= toDate;
    if (fromDate && isDateRangeValid) {
      filters.from_date = fromDate;
    }
    if (toDate && isDateRangeValid) {
      filters.to_date = toDate;
    }

    if (state.statusFilter !== "all") {
      filters.status = state.statusFilter;
    }

    if (state.sortField) {
      filters.column_name = state.sortField;
      filters.order = state.sortDirection.toUpperCase() as "ASC" | "DESC";
    }

    return filters;
  }, [
    debouncedSearchTerm,
    state.companyId,
    state.fromDate,
    state.toDate,
    state.statusFilter,
    state.currentPage,
    state.itemsPerPage,
    state.sortField,
    state.sortDirection,
  ]);

  // Auto-fetch when filters change
  useEffect(() => {
    const fetchSubscriptionPlans = async () => {
      setState((prev) => ({ ...prev, loading: true, error: null }));

      const result = await service.getSubscriptionPlans(filters);

      if (result.success && result.data) {
        const total = result.data.total ?? 0;
        const limit = result.data.limit ?? 10;

        setState((prev) => ({
          ...prev,
          subscriptionPlans: result.data.data ?? [],
          total,
          totalPages: Math.ceil(total / limit),
          loading: false,
          error: null,
        }));
      } else {
        setState((prev) => ({
          ...prev,
          subscriptionPlans: [],
          total: 0,
          totalPages: 0,
          loading: false,
          error: result.message,
        }));
      }
    };

    fetchSubscriptionPlans();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filters]);

  // Action handlers
  const setSearchTerm = useCallback((term: string) => {
    setState((prev) => ({ ...prev, searchTerm: term, currentPage: 1 }));
  }, []);

  const setCompanyId = useCallback((id: string) => {
    setState((prev) => ({ ...prev, companyId: id, currentPage: 1 }));
  }, []);

  const setFromDate = useCallback((date: string) => {
    setState((prev) => {
      // If From Date changes after To Date is selected, reset To Date.
      const hasFromDateChanged = prev.fromDate !== date;
      const toDate = prev.toDate && hasFromDateChanged ? "" : prev.toDate;
      return { ...prev, fromDate: date, toDate, currentPage: 1 };
    });
  }, []);

  const setToDate = useCallback((date: string) => {
    setState((prev) => {
      // If To Date is set before From Date, move From Date to match To Date
      const fromDate =
        prev.fromDate && date && date < prev.fromDate ? date : prev.fromDate;
      return { ...prev, fromDate, toDate: date, currentPage: 1 };
    });
  }, []);

  const setStatusFilter = useCallback(
    (filter: "all" | "active" | "expired" | "upcoming") => {
      setState((prev) => ({
        ...prev,
        statusFilter: filter,
        currentPage: 1,
      }));
    },
    []
  );

  const setSortField = useCallback((field: string | null) => {
    setState((prev) => ({ ...prev, sortField: field }));
  }, []);

  const setSortDirection = useCallback((direction: "ASC" | "DESC") => {
    setState((prev) => ({ ...prev, sortDirection: direction }));
  }, []);

  const setCurrentPage = useCallback((page: number) => {
    setState((prev) => ({ ...prev, currentPage: page }));
  }, []);

  const setItemsPerPage = useCallback((items: number) => {
    setState((prev) => ({ ...prev, itemsPerPage: items, currentPage: 1 }));
  }, []);

  const clearFilters = useCallback(() => {
    setState((prev) => ({
      ...prev,
      searchTerm: "",
      companyId: "",
      fromDate: "",
      toDate: "",
      statusFilter: "all",
      currentPage: 1,
    }));
  }, []);

  const refreshData = useCallback(async () => {
    setState((prev) => ({ ...prev, loading: true, error: null }));

    const result = await service.getSubscriptionPlans(filters);

    if (result.success && result.data) {
      const total = result.data.total ?? 0;
      const limit = result.data.limit ?? 10;

      setState((prev) => ({
        ...prev,
        subscriptionPlans: result.data.data ?? [],
        total,
        totalPages: Math.ceil(total / limit),
        loading: false,
        error: null,
      }));
    } else {
      setState((prev) => ({
        ...prev,
        subscriptionPlans: [],
        total: 0,
        totalPages: 0,
        loading: false,
        error: result.message,
      }));
    }
  }, [service, filters]);

  const actions: UseSubscriptionPlanActions = {
    setSearchTerm,
    setCompanyId,
    setFromDate,
    setToDate,
    setStatusFilter,
    setSortField,
    setSortDirection,
    setCurrentPage,
    setItemsPerPage,
    clearFilters,
    refreshData,
  };

  return {
    ...state,
    loading: state.loading || service.loading,
    ...actions,
  };
}

export default useSubscriptionPlan;
