
import React, { useState, useMemo } from 'react';
import { ArrowUpDown, ChevronRight, ChevronDown, Folder, FileText, Search } from 'lucide-react';
import { TopicNode } from '../types';

type SortMode = 'none' | 'recent' | 'alpha' | 'count';

const getLatestTimestamp = (node: TopicNode): number => {
  const parsed = node.lastMessage ? Date.parse(node.lastMessage.timestamp) : 0;
  let latest = Number.isNaN(parsed) ? 0 : parsed;
  node.children.forEach((child) => {
    const childLatest = getLatestTimestamp(child);
    if (childLatest > latest) latest = childLatest;
  });
  return latest;
};

const sortNodes = (nodes: TopicNode[], mode: SortMode): TopicNode[] => {
  if (mode === 'none') {
    return nodes;
  }
  const sorted = [...nodes];
  if (mode === 'alpha') {
    return sorted.sort((a, b) => a.name.localeCompare(b.name));
  }
  if (mode === 'count') {
    return sorted.sort((a, b) => (b.messageCount - a.messageCount) || a.name.localeCompare(b.name));
  }
  return sorted.sort((a, b) => (getLatestTimestamp(b) - getLatestTimestamp(a)) || a.name.localeCompare(b.name));
};

interface TopicTreeProps {
  root: TopicNode;
  onSelect: (topic: string) => void;
  selectedTopic: string | null;
  recentTopics: Record<string, number>;
  topicFilters: { topic: string; view: boolean }[];
  applyViewFilter: boolean;
}

const TopicNodeView: React.FC<{
  node: TopicNode;
  level: number;
  onSelect: (topic: string) => void;
  selectedTopic: string | null;
  recentTopics: Record<string, number>;
  topicFilters: { topic: string; view: boolean }[];
  applyViewFilter: boolean;
  sortMode: SortMode;
}> = ({ node, level, onSelect, selectedTopic, recentTopics, topicFilters, applyViewFilter, sortMode }) => {
  const [isOpen, setIsOpen] = useState(node.isExpanded ?? false);
  const hasChildren = node.children.length > 0;
  const isSelected = selectedTopic === node.fullName;
  const isRecent = Boolean(recentTopics[node.fullName]);

  const toggle = (e: React.MouseEvent) => {
    e.stopPropagation();
    if (hasChildren) setIsOpen(!isOpen);
    onSelect(node.fullName);
  };

  return (
    <div className="font-mono topic-font">
      <div 
        onClick={toggle}
        className={`flex items-center py-0.5 px-2 cursor-pointer hover:bg-[color:var(--hover-bg)] transition-colors rounded ${isSelected ? 'bg-[color:var(--selected-bg)] text-[color:var(--accent-blue)]' : ''} ${isRecent ? 'flash-topic' : ''}`}
        style={{ paddingLeft: `${level * 16}px` }}
      >
        <span className="mr-1 w-4 flex justify-center">
          {hasChildren ? (
            isOpen ? <ChevronDown size={14} /> : <ChevronRight size={14} />
          ) : (
            <span className="w-2" />
          )}
        </span>
        <span className="mr-1 opacity-60">
          {hasChildren ? <Folder size={14} /> : <FileText size={14} />}
        </span>
        <span className="whitespace-normal break-all">{node.name}</span>
        {node.messageCount > 0 && (
          <span className="ml-auto topic-font opacity-40 px-1 border border-[color:var(--border)] rounded">
            {node.messageCount}
          </span>
        )}
      </div>
      {isOpen && hasChildren && (
        <div>
        {sortNodes(node.children, sortMode)
          .map(child => (
              <TopicNodeView 
                key={child.fullName} 
                node={child} 
                level={level + 1} 
                onSelect={onSelect}
                selectedTopic={selectedTopic}
                recentTopics={recentTopics}
                topicFilters={topicFilters}
                applyViewFilter={applyViewFilter}
                sortMode={sortMode}
              />
            ))}
        </div>
      )}
    </div>
  );
};

const matchTopic = (rule: string, topic: string) => {
  const trimmed = rule.trim();
  if (!trimmed) return false;
  if (trimmed === '#') return true;
  if (trimmed.endsWith('/#')) {
    const prefix = trimmed.slice(0, -2);
    return topic.startsWith(prefix);
  }
  return trimmed === topic;
};

export const TopicTree: React.FC<TopicTreeProps> = ({ root, onSelect, selectedTopic, recentTopics, topicFilters, applyViewFilter }) => {
  const [filter, setFilter] = useState('');
  const [sortMode, setSortMode] = useState<SortMode>('none');
  const normalizedFilter = filter.trim().toLowerCase();

  const filtered = useMemo(() => {
    const shouldHide = (topic: string) => {
      if (!applyViewFilter) return false;
      return topicFilters.some((entry) => !entry.view && matchTopic(entry.topic, topic));
    };

    if (!normalizedFilter) {
      return sortNodes(root.children.filter((node) => !shouldHide(node.fullName)), sortMode);
    }

    const walk = (node: TopicNode): TopicNode | null => {
      if (shouldHide(node.fullName)) return null;
      const matches = node.fullName.toLowerCase().includes(normalizedFilter);
      const nextChildren = node.children
        .map(walk)
        .filter((child): child is TopicNode => child !== null);
      if (matches || nextChildren.length > 0) {
        return { ...node, children: sortNodes(nextChildren, sortMode), isExpanded: true };
      }
      return null;
    };

    return sortNodes(root.children
      .map(walk)
      .filter((child): child is TopicNode => child !== null), sortMode);
  }, [applyViewFilter, normalizedFilter, root.children, sortMode, topicFilters]);

  return (
    <div className="flex flex-col h-full bg-[color:var(--bg-panel)] border-r border-[color:var(--border)] topic-font">
      <div className="p-3 border-b border-[color:var(--border)]">
        <div className="flex items-center gap-2">
          <div className="relative flex-1">
            <Search className="absolute left-2 top-2.5 opacity-40" size={14} />
            <input 
              type="text" 
              placeholder="Filtrer les topics..."
              className="w-full bg-[color:var(--bg-code)] border border-[color:var(--border)] rounded py-1.5 pl-8 pr-8 text-xs focus:outline-none focus:border-[color:var(--focus-ring)]"
              value={filter}
              onChange={(e) => setFilter(e.target.value)}
            />
            {filter && (
              <button
                type="button"
                className="absolute right-2 top-1.5 text-xs opacity-50 hover:opacity-80"
                onClick={() => setFilter('')}
                title="Effacer le filtre"
              >
                ×
              </button>
            )}
          </div>
          <div className="flex items-center gap-1 text-[10px] opacity-70">
            <ArrowUpDown size={12} />
            <select
              value={sortMode}
              onChange={(e) => setSortMode(e.target.value as SortMode)}
              className="bg-[color:var(--bg-code)] border border-[color:var(--border)] rounded px-2 py-1 text-[10px]"
              title="Trier les topics"
            >
              <option value="none">Sans tri</option>
              <option value="recent">Derniers messages</option>
              <option value="alpha">Ordre alphabétique</option>
              <option value="count">Messages (desc)</option>
            </select>
          </div>
        </div>
      </div>
      <div className="flex-1 overflow-auto p-2 custom-scrollbar">
        {filtered.map(node => (
          <TopicNodeView 
            key={node.fullName} 
            node={node} 
            level={0} 
            onSelect={onSelect}
            selectedTopic={selectedTopic}
            recentTopics={recentTopics}
            topicFilters={topicFilters}
            applyViewFilter={applyViewFilter}
            sortMode={sortMode}
          />
        ))}
        {filtered.length === 0 && (
          <div className="text-center py-10 text-xs opacity-40 italic">
            Aucun topic trouvé...
          </div>
        )}
      </div>
    </div>
  );
};
