import React, { useCallback, useMemo } from 'react';
import {
    Box,
    Button,
    Tooltip,
    Autocomplete,
    TextField,
    createFilterOptions
} from '@mui/material';
import { TrackerPart } from '../../models/ProgressTrackerModels';
import {ucFirst} from "../../utils/ProgressTrackerUtils";

// Interface for hierarchy information
interface FilterHierarchy {
    category: string;
    level: number;
    parentCategory: string | null;
    categoryName: string;
    isRoot: boolean;
}

// Helper function to check if an option is the "Show All" option
function isShowAllOption(option: TrackerPart | null): option is TrackerPart {
    return option !== null && option.trackerPartId === -1;
}

interface PTFilterControlsProps {
    selectedPartType: string | null;
    hierarchySelections: { [category: string]: TrackerPart | null };
    partsHierarchy: { [category: string]: FilterHierarchy };
    partTypeGroups: { [key: string]: TrackerPart[] };
    activeTabIndex: number;
    parts: TrackerPart[]; // Added missing parts prop
    getParentCategories: (category: string) => string[];
    onFilterChange: (category: string, part: TrackerPart | null) => void;
    onClearFilters: () => void;
    onShowRules: () => void;
}

export const PTFilterControls = ({
    selectedPartType,
    hierarchySelections,
    partsHierarchy,
    partTypeGroups,
    activeTabIndex,
    parts,
    getParentCategories,
    onFilterChange,
    onClearFilters,
    onShowRules
}: PTFilterControlsProps) => {
    // Function to get non-root filter categories for a category
    const getNonRootFilterCategories = useCallback((category: string): string[] => {
        // Get parent categories in hierarchical order
        const parentCategories = getParentCategories(category);

        // Filter out root categories
        const nonRootParents = parentCategories.filter(cat =>
            !partsHierarchy[cat]?.isRoot
        );

        // Add the current category if it's not a root
        if (!partsHierarchy[category]?.isRoot) {
            nonRootParents.push(category);
        }

        return nonRootParents;
    }, [getParentCategories, partsHierarchy]);

    // Function to check if a filter is disabled based on parent selection
    const isFilterDisabled = useCallback((category: string): boolean => {
        const hierarchyInfo = partsHierarchy[category];

        // Root categories are never disabled
        if (!hierarchyInfo || !hierarchyInfo.parentCategory) {
            return false;
        }

        // Disabled if parent category doesn't have a selection
        const parentCategory = hierarchyInfo.parentCategory;
        return !hierarchySelections[parentCategory];
    }, [partsHierarchy, hierarchySelections]);

    /**
     * Handle filter change with proper "Show All" option handling
     */
    const handleFilterChange = (category: string, option: TrackerPart | null) => {
        // First check if this is already the selected value
        if (option === hierarchySelections[category]) {
            return; // No change needed
        }

        // If we're switching to or from a "Show All" option, make sure to update visibility
        const currentIsShowAll = hierarchySelections[category] ? isShowAllOption(hierarchySelections[category]) : false;
        const newIsShowAll = option ? isShowAllOption(option) : false;

        // Call the parent handler to update selections
        onFilterChange(category, option);

        // If changing between normal selection and "Show All", we need special handling
        if (currentIsShowAll !== newIsShowAll) {
            // This will be handled in the state manager's handleFilterChange method
            // which will call loadSummaryView or update visiblePartIds accordingly
        }
    };

    /**
     * Create a "Show All" option for a category
     */
    const createShowAllOption = (category: string): TrackerPart => {
        const categoryName = partsHierarchy[category]?.categoryName || category;
        return {
            trackerPartId: -1, // Special ID for "Show All" option
            partId: -1,
            reference: `SHOW_ALL_${category}`,
            name: `Show all ${ucFirst(categoryName)}(s)`,
            category: category,
            parent: -1,
            calculationRulePreset: undefined
        } as TrackerPart;
    };

    /**
     * Get filter options for a category, including "Show All" option
     */
    const getFilterOptions = (category: string): TrackerPart[] => {
        // First, get all parts that match the category
        let options = parts.filter(part => part.category === category);

        // Then filter by parent relationship if applicable
        const hierarchyInfo = partsHierarchy[category];
        if (hierarchyInfo && hierarchyInfo.parentCategory) {
            const parentCategory = hierarchyInfo.parentCategory;
            const parentSelection = hierarchySelections[parentCategory];

            // If parent is selected (and not a "Show All" option), filter by parent ID
            if (parentSelection && !isShowAllOption(parentSelection)) {
                options = options.filter(part => part.parent === parentSelection.trackerPartId);
            }
        }

        // Add "Show All" option at the start
        const showAllOption = createShowAllOption(category);
        return [showAllOption, ...options].sort((a, b) => {
            // Always put "Show All" first
            if (a.trackerPartId === -1) return -1;
            if (b.trackerPartId === -1) return 1;
            // Then sort by name
            return a.name.localeCompare(b.name);
        });
    };

    const category = selectedPartType || "";
    const currentTabPart = hierarchySelections[category];
    const hasValidRules = currentTabPart && !isShowAllOption(currentTabPart) && currentTabPart.calculationRulePreset;

    // Get only non-root filter categories for the current tab
    const filterChain = selectedPartType ? getNonRootFilterCategories(selectedPartType) : [];

    return (
        <div className="controls-container">
            {/* Rules Button */}
            <Tooltip
                title={!hasValidRules ? "Please select a specific part to view calculation rules" : ""}
                arrow
            >
                <span> {/* Wrap button in span for tooltip to work when disabled */}
                    <Button
                        key="calculation-rules-button"
                        variant="outlined"
                        onClick={onShowRules}
                        disabled={!hasValidRules}
                        sx={{
                            textTransform: 'none',
                            marginRight: '10px',
                            // Apply muted styling when disabled
                            opacity: hasValidRules ? 1 : 0.7
                        }}
                    >
                        ⓘ Calculation Rules
                    </Button>
                </span>
            </Tooltip>

            {/* Filter dropdowns */}
            {filterChain.map(filterCategory => {
                const options = getFilterOptions(filterCategory);
                const disabled = isFilterDisabled(filterCategory);
                const categoryName = partsHierarchy[filterCategory]?.categoryName || filterCategory;
                const showAllOption = options.find(opt => opt.trackerPartId === -1);
                const currentValue = hierarchySelections[filterCategory];
                if (!currentValue) {
                    onFilterChange(filterCategory, showAllOption);
                    return '';
                }

                // Find the "Show All" option to use as default when clearing

                // Use a custom filter to match both by ref and name
                const filterOptions = createFilterOptions({
                    stringify: (option: TrackerPart) =>
                        `${option.reference} ${option.name}`
                });

                return (
                    <Autocomplete
                        key={filterCategory}
                        id={`filter-${filterCategory}`}
                        options={options}
                        getOptionLabel={(part) => part.trackerPartId === -1 ?
                            part.name :
                            `${part.name}`}
                        renderInput={(params) => (
                            <TextField
                                {...params}
                                label={`Select ${ucFirst(categoryName)}`}
                                variant="outlined"
                                size="small"
                                error={disabled && activeTabIndex > 1} // Highlight parent dropdowns in error state
                            />
                        )}
                        value={currentValue}
                        onChange={(_, newPart) => {
                            // If user clears the selection, always use the "Show All" option
                            // No need to check isRoot since filterChain already filters out root categories
                            if (!newPart) {
                                onFilterChange(filterCategory, showAllOption);
                            } else {
                                onFilterChange(filterCategory, newPart);
                            }
                        }}
                        isOptionEqualToValue={(option, value) => {
                            if (!option || !value) return false;
                            return option.trackerPartId === value.trackerPartId;
                        }}
                        disabled={disabled}
                        noOptionsText={disabled ? `Select a ${partsHierarchy[filterCategory]?.parentCategory || 'parent'} first` : "No options available"}
                        sx={{ width: '20rem', marginRight: '10px', display: 'inline-block' }}
                        filterOptions={filterOptions}
                        clearIcon={
                            // For the right-most filter (current category level), show a "reset" icon instead of a clear icon
                            // No need to check isRoot since filterChain already filters out root categories
                            filterCategory === category
                                ? <span title="Show all">↺</span>
                                : undefined // Use default clear icon
                        }
                    />
                    // TODO pt-future: Use flexbox for filter width instead of hardcoded widths.
                );
            })}

            {/* Todo pt: Thoroughly remove this functionality: */}
            {/* Clear filters button */}
            {/* {Object.entries(hierarchySelections).some(([cat]) => !partsHierarchy[cat]?.isRoot) && (
                <Button
                    variant="outlined"
                    color="secondary"
                    onClick={onClearFilters}
                    sx={{ textTransform: 'none' }}
                >
                    Clear Filters
                </Button>
            )} */}
        </div>
    );
};

export default PTFilterControls;
