import { useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { ts } from '../../i18n/server';
import { useCollapsibleGroups } from '../../hooks/useCollapsibleGroups';
import { trackEvent } from '../../lib/analytics';
import { POI_CATEGORY_LOGOS } from '../../lib/consts';
import type { POICategoryGroup } from '../../types';
import InfoPopup from '../ui/InfoPopup';
import { SearchInput } from '../ui/SearchInput';
import { PillToggle } from '../ui/PillToggle';
import { PillGroup } from '../ui/PillGroup';
import { InfoIcon, ChevronIcon, CloseIcon } from '../ui/icons';
import { IconButton } from '../ui/IconButton';

interface POIPaneProps {
  groups: POICategoryGroup[];
  selectedCategories: Set<string>;
  onCategoriesChange: (categories: Set<string>) => void;
  poiCount: number;
  onNavigateToSource?: (slug: string) => void;
  onClose?: () => void;
}

export default function POIPane({
  groups,
  selectedCategories,
  onCategoriesChange,
  poiCount: _poiCount,
  onNavigateToSource,
  onClose,
}: POIPaneProps) {
  const { t } = useTranslation();
  const [searchTerm, setSearchTerm] = useState('');
  const [isGroupExpanded, toggleCollapse] = useCollapsibleGroups();
  const [showInfo, setShowInfo] = useState(false);

  const allCategories = groups.flatMap((g) => g.categories);

  const toggleCategory = (category: string) => {
    const newSet = new Set(selectedCategories);
    const wasSelected = newSet.has(category);
    if (wasSelected) {
      newSet.delete(category);
    } else {
      newSet.add(category);
    }
    trackEvent('POI Toggle', { category, selected: String(!wasSelected) });
    onCategoriesChange(newSet);
  };

  const selectAll = () => {
    trackEvent('POI Select All');
    onCategoriesChange(new Set(allCategories));
  };

  const selectNone = () => {
    trackEvent('POI Select None');
    onCategoriesChange(new Set());
  };

  const toggleGroup = useCallback(
    (groupName: string) => {
      const group = groups.find((g) => g.name === groupName);
      if (!group) return;
      const allSelected = group.categories.every((c) => selectedCategories.has(c));
      const newSet = new Set(selectedCategories);
      if (allSelected) {
        group.categories.forEach((c) => newSet.delete(c));
      } else {
        group.categories.forEach((c) => newSet.add(c));
      }
      onCategoriesChange(newSet);
    },
    [groups, selectedCategories, onCategoriesChange]
  );

  const lowerSearch = searchTerm.toLowerCase();

  const filteredGroups = groups
    .map((group) => {
      if (!searchTerm) return group;
      const matchingCats = group.categories.filter((c) => c.toLowerCase().includes(lowerSearch));
      const groupMatches = group.name.toLowerCase().includes(lowerSearch);
      if (groupMatches) return group;
      if (matchingCats.length === 0) return null;
      return { ...group, categories: matchingCats };
    })
    .filter(Boolean) as POICategoryGroup[];

  const selectedCount = selectedCategories.size;

  return (
    <div className="flex h-full min-h-0 flex-col overflow-hidden bg-white shadow-lg dark:bg-warm-900">
      <div className="flex-shrink-0 px-3 pt-3 pb-2">
        <div className="flex items-center gap-2">
          <span className="text-xs font-semibold text-warm-500 dark:text-warm-400 uppercase tracking-wide">
            {t('poiPane.pois')}
          </span>
          <span className="text-xs text-warm-400 dark:text-warm-500">
            {selectedCount}/{allCategories.length}
          </span>
          <IconButton onClick={() => setShowInfo(true)} title={t('poiPane.dataSourceInfo')}>
            <InfoIcon />
          </IconButton>
          <div className="flex gap-1 ml-auto items-center">
            <button
              onClick={selectAll}
              className="px-2 py-0.5 text-xs rounded border border-warm-300 dark:border-warm-700 text-warm-600 dark:text-warm-400 hover:bg-warm-50 dark:hover:bg-warm-700"
            >
              {t('common.all')}
            </button>
            <button
              onClick={selectNone}
              className="px-2 py-0.5 text-xs rounded border border-warm-300 dark:border-warm-700 text-warm-600 dark:text-warm-400 hover:bg-warm-50 dark:hover:bg-warm-700"
            >
              {t('common.none')}
            </button>
            {onClose && (
              <button
                onClick={onClose}
                className="ml-1 p-0.5 text-warm-400 hover:text-warm-700 dark:hover:text-warm-300"
                title={t('common.close')}
              >
                <CloseIcon className="w-4 h-4" />
              </button>
            )}
          </div>
        </div>

        {showInfo && (
          <InfoPopup
            title={t('poiPane.pointsOfInterest')}
            onClose={() => setShowInfo(false)}
            sourceLink={
              onNavigateToSource
                ? {
                    label: t('common.viewDataSource'),
                    onClick: () => {
                      onNavigateToSource('osm-pois');
                      setShowInfo(false);
                    },
                  }
                : undefined
            }
          >
            <p className="text-sm text-warm-700 dark:text-warm-300 mb-4 leading-relaxed">
              {t('poiPane.poiDescription')}
            </p>
          </InfoPopup>
        )}
      </div>

      <div className="flex-1 min-h-0 overflow-y-auto overscroll-contain border-t border-warm-200 dark:border-warm-700">
        <div className="px-3 pt-2 pb-1">
          <SearchInput
            value={searchTerm}
            onChange={setSearchTerm}
            placeholder={t('poiPane.searchCategories')}
          />
        </div>
        {filteredGroups.map((group) => {
          const groupSelected = group.categories.filter((c) => selectedCategories.has(c)).length;
          const allInGroupSelected = groupSelected === group.categories.length;
          const someInGroupSelected = groupSelected > 0 && !allInGroupSelected;
          const isCollapsed = !isGroupExpanded(group.name) && !searchTerm;

          return (
            <div key={group.name}>
              <div className="flex items-center gap-1 px-3 py-1.5 bg-warm-50 dark:bg-navy-950 border-b border-warm-100 dark:border-navy-700 sticky top-0 z-10">
                <button
                  onClick={() => toggleCollapse(group.name)}
                  className={`p-0.5 text-warm-400 hover:text-warm-600 transition-transform ${isCollapsed ? '' : 'rotate-90'}`}
                >
                  <ChevronIcon direction="right" className="w-3 h-3" />
                </button>
                <PillToggle
                  label={ts(group.name)}
                  active={allInGroupSelected}
                  indeterminate={someInGroupSelected}
                  onClick={() => toggleGroup(group.name)}
                  size="xs"
                />
                <span className="text-xs text-warm-400 ml-auto">
                  {groupSelected}/{group.categories.length}
                </span>
              </div>
              {!isCollapsed && (
                <div className="px-3 py-2">
                  <PillGroup>
                    {group.categories.map((category) => {
                      const logo = POI_CATEGORY_LOGOS[category];
                      return (
                        <PillToggle
                          key={category}
                          label={ts(category)}
                          icon={
                            logo ? (
                              <img
                                src={logo}
                                alt=""
                                aria-hidden="true"
                                loading="lazy"
                                referrerPolicy="no-referrer"
                                className="h-4 w-4 shrink-0 rounded-[3px] bg-white object-contain p-0.5"
                              />
                            ) : undefined
                          }
                          active={selectedCategories.has(category)}
                          onClick={() => toggleCategory(category)}
                          size="xs"
                        />
                      );
                    })}
                  </PillGroup>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
