import { useState, useEffect, useCallback } from 'react';
import { ProgressTrackerStateManager } from '../services/ProgressTrackerStateManager';
import { ProgressTrackerAPI } from '../services/ProgressTrackerAPI';
import {
  TrackerPart,
  CriterionState,
  MarkData,
  Student
} from '../models/ProgressTrackerModels';

/**
 * Custom hook to use the ProgressTrackerStateManager in React components
 */
export function useProgressTracker(trackerId: number, moduleId: number, useMockData: boolean = false, apiBaseUrl: string = '/v1') {
  // Create API instance
  const api = new ProgressTrackerAPI({
    baseUrl: apiBaseUrl,
    useMockData
  });

  // Create state manager instance
  const [stateManager] = useState<ProgressTrackerStateManager>(
    () => new ProgressTrackerStateManager(trackerId, moduleId, api)
  );

  // Local state to trigger re-renders when the state manager changes
  const [, setUpdateCounter] = useState(0);

  // Initialize state manager
  useEffect(() => {
    // Register callback for state changes
    stateManager.registerStateChangeCallback(() => {
      // Increment counter to trigger re-render
      setUpdateCounter(prevCounter => prevCounter + 1);
    });

    // Initialize the state manager
    stateManager.initialize();
  }, [stateManager]);

  // Callbacks for various actions
  const handleFilterChange = useCallback(
    (category: string, part: TrackerPart | null) => stateManager.handleFilterChange(category, part),
    [stateManager]
  );

  const handleTabChange = useCallback(
    (index: number) => stateManager.handleTabChange(index),
    [stateManager]
  );

  const handleClearFilters = useCallback(
    () => stateManager.handleClearFilters(),
    [stateManager]
  );

  const handleShowRules = useCallback(
    () => stateManager.showRuleDetails(),
    [stateManager]
  );

  const handlePartHeaderClick = useCallback(
    (partId: number) => stateManager.handlePartHeaderClick(partId),
    [stateManager]
  );

  const handleMarkChange = useCallback(
    (partId: number, studentId: number, field: keyof MarkData, value: any) => 
      stateManager.handleMarkChange(partId, studentId, field, value),
    [stateManager]
  );

  const handleCriterionChange = useCallback(
    (partId: number, studentId: number, criterionName: string, value: CriterionState | null) => 
      stateManager.handleCriterionChange(partId, studentId, criterionName, value),
    [stateManager]
  );

  const handleCriterionHeaderClick = useCallback(
    (partId: number, criterionName: string) => 
      stateManager.handleCriterionHeaderClick(partId, criterionName),
    [stateManager]
  );

  const handleSortRequest = useCallback(
    (partId: number, field: keyof Student | 'score' | 'grade') => 
      stateManager.handleSortRequest(partId, field),
    [stateManager]
  );

  const handleSaveMarkData = useCallback(
    (partId: number) => stateManager.saveMarkData(partId),
    [stateManager]
  );

  const handleCloseRuleDetails = useCallback(
    () => stateManager.closeRuleDetails(),
    [stateManager]
  );

  const handleCloseSnackbar = useCallback(
    () => stateManager.closeSnackbar(),
    [stateManager]
  );

  const handleReloadMarkDataForPart = useCallback(
    (partId: number) => stateManager.reloadMarkDataForPart(partId),
    [stateManager]
  );

  const handleReloadMarkDataForPartAndParents = useCallback(
    (partId: number) => stateManager.reloadMarkDataForPartAndParents(partId),
    [stateManager]
  );

  const handleReloadCurrentView = useCallback(
    () => stateManager.reloadCurrentView(),
    [stateManager]
  );

  const handleReloadSummaryViewAndParents = useCallback(
    (category: string) => stateManager.reloadSummaryViewAndParents(category),
    [stateManager]
  );

  // Helper methods
  const getPartTypeGroups = useCallback(
    () => stateManager.getPartTypeGroups(),
    [stateManager]
  );

  const getParentCategories = useCallback(
    (category: string) => stateManager.getParentCategories(category),
    [stateManager]
  );

  const getChildCategories = useCallback(
    (category: string) => stateManager.getChildCategories(category),
    [stateManager]
  );

  const shouldShowContent = useCallback(
    (category: string) => stateManager.shouldShowContent(category),
    [stateManager]
  );

  const getMissingFilterName = useCallback(
    (category: string) => stateManager.getMissingFilterName(category),
    [stateManager]
  );

  const getDeepestSelectedFilter = useCallback(
    () => stateManager.getDeepestSelectedFilter(),
    [stateManager]
  );

  // Derived data methods
  const getUniquePartTypes = useCallback(
    () => stateManager.getUniquePartTypes(),
    [stateManager]
  );

  // Grade-related helper methods
  const getGradesForPart = useCallback(
    (partId: number) => stateManager.getGradesForPart(partId),
    [stateManager]
  );

  const getGradeSchemeForPart = useCallback(
    (partId: number) => stateManager.getGradeSchemeForPart(partId),
    [stateManager]
  );

  const getGradeDisplayName = useCallback(
    (gradeRef: string, partId: number) => stateManager.getGradeDisplayName(gradeRef, partId),
    [stateManager]
  );

  const getGradeOptionsForPart = useCallback(
    (partId: number) => stateManager.getGradeOptionsForPart(partId),
    [stateManager]
  );
  
  console.log('PT INTERNAL STATE: stateManager', stateManager);

  // Return all state and actions
  return {
    // State
    tracker: stateManager.tracker,
    parts: stateManager.parts,
    partGuis: stateManager.partGuis,
    students: stateManager.students,
    partsById: stateManager.partsById,
    partsHierarchy: stateManager.partsHierarchy,
    markDataByPart: stateManager.markDataByPart,
    markScreenLoading: stateManager.markScreenLoading,
    loading: stateManager.loading,
    error: stateManager.error,
    selectedPartType: stateManager.selectedPartType,
    hierarchySelections: stateManager.hierarchySelections,
    visiblePartIds: stateManager.visiblePartIds,
    activeTabIndex: stateManager.activeTabIndex,
    showSummaryView: stateManager.showSummaryView,
    summaryParts: stateManager.summaryParts,
    summaryPartMarks: stateManager.summaryPartMarks,
    summaryViewLoading: stateManager.summaryViewLoading,
    rulePresetDialogOpen: stateManager.rulePresetDialogOpen,
    ruleDetails: stateManager.ruleDetails,
    ruleLoading: stateManager.ruleLoading,
    hasChangesByPart: stateManager.hasChangesByPart,
    manuallyModifiedCriteriaByPart: stateManager.manuallyModifiedCriteriaByPart,
    sortConfigByPart: stateManager.sortConfigByPart,
    saveStatusByPart: stateManager.saveStatusByPart,
    snackbar: stateManager.snackbar,
    gradeSchemes: stateManager.gradeSchemes,
    grades: stateManager.grades,

    // Helper methods
    getPartTypeGroups,
    getParentCategories,
    getChildCategories,
    shouldShowContent,
    getMissingFilterName,
    getDeepestSelectedFilter,
    getUniquePartTypes,
    // Grade-related helper methods
    getGradesForPart,
    getGradeSchemeForPart,
    getGradeDisplayName,
    getGradeOptionsForPart,

    // Actions
    onFilterChange: handleFilterChange,
    onTabChange: handleTabChange,
    onClearFilters: handleClearFilters,
    onShowRules: handleShowRules,
    onPartHeaderClick: handlePartHeaderClick,
    onMarkChange: handleMarkChange,
    onCriterionChange: handleCriterionChange,
    onCriterionHeaderClick: handleCriterionHeaderClick,
    onSortRequest: handleSortRequest,
    onSaveMarkData: handleSaveMarkData,
    // Use the property names expected by ModuleProgressTracker
    rulePresetDialogOnClose: handleCloseRuleDetails,  // Changed from onCloseRuleDetails
    onSnackbarClose: handleCloseSnackbar,   // Changed from onCloseSnackbar    // Loading methods
    loadMarkDataForPart: useCallback(
      (partId: number) => stateManager.loadMarkDataForPart(partId),
      [stateManager]
    ),
    loadSummaryView: useCallback(
      (category: string) => stateManager.loadSummaryView(category),
      [stateManager]
    ),    // Reload methods
    reloadMarkDataForPart: handleReloadMarkDataForPart,
    reloadMarkDataForPartAndParents: handleReloadMarkDataForPartAndParents,
    reloadSummaryViewAndParents: handleReloadSummaryViewAndParents,
    reloadCurrentView: handleReloadCurrentView,
    reloadSummaryViewAndParents: handleReloadSummaryViewAndParents,
    // Setters for state manager
    setManuallyModifiedCriteria: useCallback(
      (partId: number, modifiedCriteria: { [studentId: number]: { [criterionName: string]: boolean } }) => {
        const updatedCriteria = {
          ...stateManager.manuallyModifiedCriteriaByPart,
          [partId]: modifiedCriteria
        };
        stateManager.manuallyModifiedCriteriaByPart = updatedCriteria;
      },
      [stateManager]
    ),
    setSortConfig: useCallback(
      (partId: number, config: { sortBy: keyof Student | 'score' | 'grade' | null; sortDirection: 'asc' | 'desc' }) => {
        const updatedConfig = {
          ...stateManager.sortConfigByPart,
          [partId]: config
        };
        stateManager.sortConfigByPart = updatedConfig;
      },
      [stateManager]
    ),
    setSaveStatus: useCallback(
      (partId: number, status: 'idle' | 'saving' | 'saved' | 'error') => {
        const updatedStatus = {
          ...stateManager.saveStatusByPart,
          [partId]: status
        };
        stateManager.saveStatusByPart = updatedStatus;
      },
      [stateManager]
    ),
    setSnackbar: useCallback(
      (snackbar: { open: boolean; message: string; severity: 'success' | 'error' | 'info' | 'warning' }) => {
        stateManager.snackbar = snackbar;
      },
      [stateManager]
    ),
  };
}