'use client';

import { useState, useEffect, useCallback } from 'react';
import TreeNode from './TreeNode';
import { taxonomy, getDomainSubcodeCount, getSubcodeCount } from '@/lib/taxonomy/data';
import type { SelectedSubcode } from '@/lib/taxonomy/types';

interface TaxonomyTreeProps {
  searchQuery: string;
  searchResults: {
    domains: string[];
    categories: string[];
    subcodes: string[];
  };
  selectedSubcode: SelectedSubcode | null;
  onSelectSubcode: (subcode: SelectedSubcode | null) => void;
}

export default function TaxonomyTree({
  searchQuery,
  searchResults,
  selectedSubcode,
  onSelectSubcode,
}: TaxonomyTreeProps) {
  const [expandedDomains, setExpandedDomains] = useState<Set<string>>(new Set());
  const [expandedCategories, setExpandedCategories] = useState<Set<string>>(new Set());

  // Auto-expand nodes when search results change
  useEffect(() => {
    if (searchQuery) {
      const domainsToExpand = new Set<string>();
      const categoriesToExpand = new Set<string>();

      // Expand domains that have matches
      searchResults.domains.forEach((d) => domainsToExpand.add(d));

      // Expand parent domains for matched categories
      searchResults.categories.forEach((c) => {
        domainsToExpand.add(c[0]);
        categoriesToExpand.add(c);
      });

      // Expand parent domains and categories for matched subcodes
      searchResults.subcodes.forEach((s) => {
        const domainKey = s[0];
        const categoryKey = s.slice(0, 2);
        domainsToExpand.add(domainKey);
        categoriesToExpand.add(categoryKey);
      });

      setExpandedDomains(domainsToExpand);
      setExpandedCategories(categoriesToExpand);
    }
  }, [searchQuery, searchResults]);

  const toggleDomain = useCallback((domainKey: string) => {
    setExpandedDomains((prev) => {
      const next = new Set(prev);
      if (next.has(domainKey)) {
        next.delete(domainKey);
      } else {
        next.add(domainKey);
      }
      return next;
    });
  }, []);

  const toggleCategory = useCallback((categoryKey: string) => {
    setExpandedCategories((prev) => {
      const next = new Set(prev);
      if (next.has(categoryKey)) {
        next.delete(categoryKey);
      } else {
        next.add(categoryKey);
      }
      return next;
    });
  }, []);

  const handleSelectSubcode = (
    subcodeKey: string,
    domainKey: string,
    domainName: string,
    categoryKey: string,
    categoryName: string,
    subcode: SelectedSubcode['subcode']
  ) => {
    onSelectSubcode({
      code: subcodeKey,
      domainKey,
      domainName,
      categoryKey,
      categoryName,
      subcode,
    });
  };

  const isSubcodeSelected = (subcodeKey: string) => {
    return selectedSubcode?.code === subcodeKey;
  };

  const isSearchMatch = (key: string) => {
    if (!searchQuery) return false;
    return (
      searchResults.domains.includes(key) ||
      searchResults.categories.includes(key) ||
      searchResults.subcodes.includes(key)
    );
  };

  // Filter to show only matches when searching
  const shouldShowDomain = (domainKey: string) => {
    if (!searchQuery) return true;
    // Show domain if it matches or any of its children match
    if (searchResults.domains.includes(domainKey)) return true;
    if (searchResults.categories.some((c) => c.startsWith(domainKey))) return true;
    if (searchResults.subcodes.some((s) => s.startsWith(domainKey))) return true;
    return false;
  };

  const shouldShowCategory = (categoryKey: string) => {
    if (!searchQuery) return true;
    if (searchResults.categories.includes(categoryKey)) return true;
    if (searchResults.subcodes.some((s) => s.startsWith(categoryKey))) return true;
    return false;
  };

  const shouldShowSubcode = (subcodeKey: string) => {
    if (!searchQuery) return true;
    return searchResults.subcodes.includes(subcodeKey);
  };

  return (
    <div className="flex flex-col gap-0.5">
      {Object.entries(taxonomy.domains).map(([domainKey, domain]) => {
        if (!shouldShowDomain(domainKey)) return null;

        return (
          <TreeNode
            key={domainKey}
            code={domainKey}
            name={domain.name}
            count={getDomainSubcodeCount(domainKey)}
            isExpanded={expandedDomains.has(domainKey)}
            level="domain"
            domainKey={domainKey}
            onToggle={() => toggleDomain(domainKey)}
            searchMatch={isSearchMatch(domainKey)}
          >
            {Object.entries(domain.categories).map(([categoryKey, category]) => {
              if (!shouldShowCategory(categoryKey)) return null;

              return (
                <TreeNode
                  key={categoryKey}
                  code={categoryKey}
                  name={category.name}
                  count={getSubcodeCount(categoryKey)}
                  isExpanded={expandedCategories.has(categoryKey)}
                  level="category"
                  domainKey={domainKey}
                  onToggle={() => toggleCategory(categoryKey)}
                  searchMatch={isSearchMatch(categoryKey)}
                >
                  {Object.entries(category.subcodes).map(([subcodeKey, subcode]) => {
                    if (!shouldShowSubcode(subcodeKey)) return null;

                    return (
                      <TreeNode
                        key={subcodeKey}
                        code={subcodeKey}
                        name={subcode.name}
                        isLeaf
                        isSelected={isSubcodeSelected(subcodeKey)}
                        level="subcode"
                        domainKey={domainKey}
                        onClick={() =>
                          handleSelectSubcode(
                            subcodeKey,
                            domainKey,
                            domain.name,
                            categoryKey,
                            category.name,
                            subcode
                          )
                        }
                        searchMatch={isSearchMatch(subcodeKey)}
                      />
                    );
                  })}
                </TreeNode>
              );
            })}
          </TreeNode>
        );
      })}
    </div>
  );
}
