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

import { useLanguage } from '../../providers/language/LanguageContext';

interface ChatItem {
  id: string;
  label: string;
  updatedAt?: string | number;
  lastMessageAt?: 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 { t } = useLanguage();
  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 (serverSearch?: string) => {
    setLoading(true);
    try {
      const params: Record<string, unknown> = { includeArchived: true };
      if (serverSearch) params.search = serverSearch;
      const response = await api.get(
        `/api/workspace/${context.instanceId}/workflows`,
        { params },
      );
      const body = response.data ?? {};
      const nested = body.data && typeof body.data === 'object' && !Array.isArray(body.data)
        ? (body.data as { workflows?: unknown })
        : null;
      const workflowsRaw =
        body.workflows ??
        nested?.workflows ??
        (Array.isArray(body.data) ? body.data : null);
      const workflows = Array.isArray(workflowsRaw) ? workflowsRaw : [];

      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 || `${t('Chat')} ${wf.id.slice(0, 8)}`,
          updatedAt: wf.updatedAt || wf.lastActivity || wf.startedAt,
          lastMessageAt: wf.lastMessageAt,
          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) {
        const currentGroup = sorted.find(g => g.featureInstanceId === context.instanceId);
        const sectionKey = currentGroup ? `section:${currentGroup.featureCode || 'workspace'}` : 'section:workspace';
        setExpandedGroups(new Set([context.instanceId, sectionKey]));
      }
    } catch (err) {
      console.error('Failed to load chats:', err);
    } finally {
      setLoading(false);
    }
  }, [context.instanceId, t]);

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

  useEffect(() => {
    const timer = setTimeout(() => {
      if (search.trim().length >= 2) {
        _loadChats(search.trim());
      } else if (search.trim().length === 0) {
        _loadChats();
      }
    }, 300);
    return () => clearTimeout(timer);
  }, [search, _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 => ({ ...g, chats: _applyFilter(g.chats) }))
    .filter(g => g.chats.length > 0);

  const _toTs = (v?: string | number): number =>
    typeof v === 'number' ? v : new Date(v || 0).getTime();

  const _allChats = _filteredGroups
    .flatMap(g => g.chats)
    .sort((a, b) => {
      const ta = _toTs(a.lastMessageAt ?? a.updatedAt);
      const tb = _toTs(b.lastMessageAt ?? b.updatedAt);
      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={t('Umbenennen')}
                >
                  ✏️
                </button>
              )}
              {archived ? (
                <button
                  className={styles.actionBtn}
                  onClick={(e) => { e.stopPropagation(); _restoreChat(chat.id); }}
                  title={t('Wiederherstellen')}
                >
                  ↩️
                </button>
              ) : (
                <button
                  className={styles.actionBtn}
                  onClick={(e) => { e.stopPropagation(); _archiveChat(chat.id); }}
                  title={t('Archivieren')}
                >
                  📦
                </button>
              )}
              {onDeleteChat && (
                <button
                  className={`${styles.actionBtn} ${styles.actionBtnDanger}`}
                  onClick={async (e) => { e.stopPropagation(); await onDeleteChat(chat.id); _loadChats(); }}
                  title={t('Löschen')}
                >
                  🗑️
                </button>
              )}
            </span>
          </>
        )}
      </div>
    );
  };

  const _featureCodeLabel = (code: string): string => {
    const labels: Record<string, string> = {
      workspace: t('KI-Arbeitsbereich'),
      commcoach: t('CommCoach'),
      trustee: t('Trustee'),
      automation: t('Automation'),
    };
    return labels[code] || code;
  };

  if (loading) return <div className={styles.loading}>{t('Chats werden geladen…')}</div>;

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

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

      {flatMode ? (
        <div className={styles.flatList}>
          {_allChats.map((chat) =>
            _renderChatItem(chat, chat.featureInstanceId || context.instanceId),
          )}
        </div>
      ) : (
        <div className={styles.tree}>
          {(() => {
            const byFeatureCode = new Map<string, ChatGroup[]>();
            for (const g of _filteredGroups) {
              const code = g.featureCode || 'workspace';
              if (!byFeatureCode.has(code)) byFeatureCode.set(code, []);
              byFeatureCode.get(code)!.push(g);
            }
            return Array.from(byFeatureCode.entries()).map(([code, instances]) => (
              <div key={code} className={styles.treeSection}>
                <div
                  className={styles.treeSectionHeader}
                  onClick={() => _toggleGroup(`section:${code}`)}
                >
                  <span className={styles.treeArrow}>
                    {expandedGroups.has(`section:${code}`) ? '\u25BC' : '\u25B6'}
                  </span>
                  <span className={styles.treeSectionLabel}>
                    {_featureCodeLabel(code)}
                  </span>
                  <span className={styles.treeGroupCount}>
                    {instances.reduce((n, g) => n + g.chats.length, 0)}
                  </span>
                </div>
                {expandedGroups.has(`section:${code}`) && instances.map((group) => (
                  <div key={group.featureInstanceId} className={styles.treeGroup}>
                    {instances.length > 1 && (
                      <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>
                    )}
                    {(instances.length === 1 || expandedGroups.has(group.featureInstanceId)) && (
                      <div className={styles.treeChildren}>
                        {group.chats.map((chat) =>
                          _renderChatItem(chat, group.featureInstanceId),
                        )}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            ));
          })()}
        </div>
      )}

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

export default ChatsTab;
