import React, { useState, useEffect, useCallback, useRef } from 'react';
import type { UdbContext } from './UnifiedDataBar';
import api from '../../api';
import styles from './ChatsTab.module.css';

interface ChatItem {
  id: string;
  label: string;
  updatedAt?: string | number;
  featureInstanceId?: string;
  featureCode?: string;
  status?: string;
}

interface ChatGroup {
  featureInstanceId: string;
  featureLabel: string;
  featureCode: string;
  chats: ChatItem[];
}

type ChatFilter = 'active' | 'archived';

interface ChatsTabProps {
  context: UdbContext;
  onSelectChat?: (chatId: string, featureInstanceId: string) => void;
  onDragStart?: (chatId: string, event: React.DragEvent) => void;
  activeWorkflowId?: string;
  onCreateNew?: () => void;
  onRenameChat?: (chatId: string, newName: string) => void | Promise<void>;
  onDeleteChat?: (chatId: string) => void | Promise<void>;
}

function _formatRelativeTime(dateStr?: string | number): string {
  if (!dateStr) return '';
  const d = typeof dateStr === 'number' ? new Date(dateStr * 1000) : new Date(dateStr);
  if (isNaN(d.getTime())) return '';
  const now = new Date();
  const diffMs = now.getTime() - d.getTime();
  const diffMin = Math.floor(diffMs / 60_000);
  const diffH = Math.floor(diffMs / 3_600_000);
  const diffDays = Math.floor(diffMs / 86_400_000);

  if (diffMin < 1) return 'gerade eben';
  if (diffMin < 60) return `${diffMin}m`;
  if (diffH < 24) return `${diffH}h`;
  if (diffDays === 1) return 'gestern';
  if (diffDays < 7) return `vor ${diffDays}d`;
  return d.toLocaleDateString([], { month: 'short', day: 'numeric' });
}

const ChatsTab: React.FC<ChatsTabProps> = ({
  context,
  onSelectChat,
  onDragStart,
  activeWorkflowId,
  onCreateNew,
  onRenameChat,
  onDeleteChat,
}) => {
  const [groups, setGroups] = useState<ChatGroup[]>([]);
  const [flatMode, setFlatMode] = useState(false);
  const [search, setSearch] = useState('');
  const [filter, setFilter] = useState<ChatFilter>('active');
  const [expandedGroups, setExpandedGroups] = useState<Set<string>>(new Set());
  const [loading, setLoading] = useState(true);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editName, setEditName] = useState('');
  const renameInputRef = useRef<HTMLInputElement>(null);

  const _loadChats = useCallback(async () => {
    setLoading(true);
    try {
      const response = await api.get(
        `/api/workspace/${context.instanceId}/workflows`,
        { params: { includeArchived: true } },
      );
      const workflows = response.data?.workflows || response.data?.data || [];

      const groupMap = new Map<string, ChatGroup>();
      for (const wf of workflows) {
        const fiId = wf.featureInstanceId || context.instanceId;
        if (!groupMap.has(fiId)) {
          groupMap.set(fiId, {
            featureInstanceId: fiId,
            featureLabel: wf.featureLabel || wf.featureCode || fiId.slice(0, 8),
            featureCode: wf.featureCode || 'workspace',
            chats: [],
          });
        }
        groupMap.get(fiId)!.chats.push({
          id: wf.id,
          label: wf.label || wf.name || `Chat ${wf.id.slice(0, 8)}`,
          updatedAt: wf.updatedAt || wf.lastActivity || wf.startedAt,
          featureInstanceId: fiId,
          featureCode: wf.featureCode,
          status: wf.status || 'active',
        });
      }

      const sorted = Array.from(groupMap.values());
      sorted.forEach(g =>
        g.chats.sort((a, b) => {
          const ta = typeof a.updatedAt === 'number' ? a.updatedAt : new Date(a.updatedAt || 0).getTime();
          const tb = typeof b.updatedAt === 'number' ? b.updatedAt : new Date(b.updatedAt || 0).getTime();
          return tb - ta;
        }),
      );
      setGroups(sorted);

      if (expandedGroups.size === 0 && sorted.length > 0) {
        setExpandedGroups(new Set([context.instanceId]));
      }
    } catch (err) {
      console.error('Failed to load chats:', err);
    } finally {
      setLoading(false);
    }
  }, [context.instanceId]);

  useEffect(() => { _loadChats(); }, [_loadChats]);

  useEffect(() => {
    if (activeWorkflowId) {
      _loadChats();
    }
  }, [activeWorkflowId]);

  useEffect(() => {
    if (editingId && renameInputRef.current) {
      renameInputRef.current.focus();
      renameInputRef.current.select();
    }
  }, [editingId]);

  const _toggleGroup = (id: string) => {
    setExpandedGroups(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  };

  const _startEditing = (chat: ChatItem) => {
    if (!onRenameChat) return;
    setEditingId(chat.id);
    setEditName(chat.label);
  };

  const _commitRename = async (chatId: string) => {
    const trimmed = editName.trim();
    setEditingId(null);
    if (!trimmed || !onRenameChat) return;
    await onRenameChat(chatId, trimmed);
    _loadChats();
  };

  const _handleRenameKeyDown = (e: React.KeyboardEvent, chatId: string) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      _commitRename(chatId);
    } else if (e.key === 'Escape') {
      setEditingId(null);
    }
  };

  const _archiveChat = useCallback(async (chatId: string) => {
    try {
      await api.patch(`/api/workspace/${context.instanceId}/workflows/${chatId}`, { status: 'archived' });
      _loadChats();
    } catch (err) {
      console.error('Failed to archive chat:', err);
    }
  }, [context.instanceId, _loadChats]);

  const _restoreChat = useCallback(async (chatId: string) => {
    try {
      await api.patch(`/api/workspace/${context.instanceId}/workflows/${chatId}`, { status: 'active' });
      _loadChats();
    } catch (err) {
      console.error('Failed to restore chat:', err);
    }
  }, [context.instanceId, _loadChats]);

  const _isArchived = (chat: ChatItem) => chat.status === 'archived';

  const _applyFilter = (chats: ChatItem[]) =>
    chats.filter(c => filter === 'archived' ? _isArchived(c) : !_isArchived(c));

  const _filteredGroups = groups
    .map(g => {
      let chats = _applyFilter(g.chats);
      if (search) {
        chats = chats.filter(c => c.label.toLowerCase().includes(search.toLowerCase()));
      }
      return { ...g, chats };
    })
    .filter(g => g.chats.length > 0);

  const _allChats = _filteredGroups
    .flatMap(g => g.chats)
    .sort((a, b) => {
      const ta = typeof a.updatedAt === 'number' ? a.updatedAt : new Date(a.updatedAt || 0).getTime();
      const tb = typeof b.updatedAt === 'number' ? b.updatedAt : new Date(b.updatedAt || 0).getTime();
      return tb - ta;
    });

  const _activeCount = groups.reduce((n, g) => n + g.chats.filter(c => !_isArchived(c)).length, 0);
  const _archivedCount = groups.reduce((n, g) => n + g.chats.filter(c => _isArchived(c)).length, 0);

  const _renderChatItem = (chat: ChatItem, featureInstanceId: string) => {
    const isActive = activeWorkflowId === chat.id;
    const isEditing = editingId === chat.id;
    const archived = _isArchived(chat);

    const itemClassName = [
      styles.chatItem,
      isActive ? styles.chatItemActive : '',
      archived ? styles.chatItemArchived : '',
    ].filter(Boolean).join(' ');

    return (
      <div
        key={chat.id}
        className={itemClassName}
        onClick={() => {
          if (!isEditing) onSelectChat?.(chat.id, featureInstanceId);
        }}
        draggable={!!onDragStart && !isEditing}
        onDragStart={(e) => {
          e.dataTransfer.setData('application/chat-id', chat.id);
          e.dataTransfer.setData('text/plain', chat.label);
          onDragStart?.(chat.id, e);
        }}
      >
        {isEditing ? (
          <input
            ref={renameInputRef}
            className={styles.renameInput}
            value={editName}
            onChange={(e) => setEditName(e.target.value)}
            onBlur={() => _commitRename(chat.id)}
            onKeyDown={(e) => _handleRenameKeyDown(e, chat.id)}
            onClick={(e) => e.stopPropagation()}
          />
        ) : (
          <>
            <span className={styles.chatDate}>
              {_formatRelativeTime(chat.updatedAt)}
            </span>
            <span
              className={styles.chatLabel}
              title={chat.label}
            >
              {chat.label}
            </span>
            <span className={styles.chatActions}>
              {onRenameChat && (
                <button
                  className={styles.actionBtn}
                  onClick={(e) => { e.stopPropagation(); _startEditing(chat); }}
                  title="Umbenennen"
                >
                  ✏️
                </button>
              )}
              {archived ? (
                <button
                  className={styles.actionBtn}
                  onClick={(e) => { e.stopPropagation(); _restoreChat(chat.id); }}
                  title="Wiederherstellen"
                >
                  ↩️
                </button>
              ) : (
                <button
                  className={styles.actionBtn}
                  onClick={(e) => { e.stopPropagation(); _archiveChat(chat.id); }}
                  title="Archivieren"
                >
                  📦
                </button>
              )}
              {onDeleteChat && (
                <button
                  className={`${styles.actionBtn} ${styles.actionBtnDanger}`}
                  onClick={async (e) => { e.stopPropagation(); await onDeleteChat(chat.id); _loadChats(); }}
                  title="Löschen"
                >
                  🗑️
                </button>
              )}
            </span>
          </>
        )}
      </div>
    );
  };

  if (loading) return <div className={styles.loading}>Lade Chats...</div>;

  return (
    <div className={styles.chatsTab}>
      <div className={styles.toolbar}>
        <input
          className={styles.search}
          type="text"
          placeholder="Suchen..."
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
        {onCreateNew && (
          <button className={styles.createBtn} onClick={() => { onCreateNew(); setTimeout(_loadChats, 500); }} title="Neuer Chat">
            +
          </button>
        )}
        <button
          className={`${styles.modeToggle} ${flatMode ? styles.modeActive : ''}`}
          onClick={() => setFlatMode(!flatMode)}
          title={flatMode ? 'Baumansicht' : 'Listenansicht'}
        >
          {flatMode ? '\uD83C\uDF33' : '\uD83D\uDCCB'}
        </button>
      </div>

      <div className={styles.filterTabs}>
        <button
          className={`${styles.filterTab} ${filter === 'active' ? styles.filterTabActive : ''}`}
          onClick={() => setFilter('active')}
        >
          Aktiv ({_activeCount})
        </button>
        <button
          className={`${styles.filterTab} ${filter === 'archived' ? styles.filterTabActive : ''}`}
          onClick={() => setFilter('archived')}
        >
          Archiv ({_archivedCount})
        </button>
      </div>

      {flatMode ? (
        <div className={styles.flatList}>
          {_allChats.map((chat) =>
            _renderChatItem(chat, chat.featureInstanceId || context.instanceId),
          )}
        </div>
      ) : (
        <div className={styles.tree}>
          {_filteredGroups.map((group) => (
            <div key={group.featureInstanceId} className={styles.treeGroup}>
              <div
                className={`${styles.treeGroupHeader} ${
                  group.featureInstanceId === context.instanceId ? styles.treeGroupCurrent : ''
                }`}
                onClick={() => _toggleGroup(group.featureInstanceId)}
              >
                <span className={styles.treeArrow}>
                  {expandedGroups.has(group.featureInstanceId) ? '\u25BC' : '\u25B6'}
                </span>
                <span className={styles.treeGroupLabel}>{group.featureLabel}</span>
                <span className={styles.treeGroupCount}>{group.chats.length}</span>
              </div>
              {expandedGroups.has(group.featureInstanceId) && (
                <div className={styles.treeChildren}>
                  {group.chats.map((chat) =>
                    _renderChatItem(chat, group.featureInstanceId),
                  )}
                </div>
              )}
            </div>
          ))}
        </div>
      )}

      {_allChats.length === 0 && (
        <div className={styles.emptyState}>
          {filter === 'archived' ? 'Keine archivierten Chats.' : 'Keine aktiven Chats.'}
        </div>
      )}
    </div>
  );
};

export default ChatsTab;
