'use client';

import { useState, useEffect, useCallback, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { publishTopic } from '@cockpit/effect-react';
import { Topics } from '@cockpit/effect-services';
import { BrowserRuntime } from '@cockpit/effect-runtime';
import { loadSessionsByProject } from './effect/agentClient';

interface SessionInfo {
  path: string;
  title: string;
  modifiedAt: string;
  firstMessages: string[];
  lastMessages: string[];
  /** Untruncated full-text corpus (title + summary + all user messages), lowercased. */
  searchText?: string;
  engine?: 'claude' | 'claude2' | 'ollama' | 'codex' | 'kimi';
}

interface ProjectSessionsModalProps {
  isOpen: boolean;
  onClose: () => void;
  cwd: string;
  onSelectSession?: (sessionId: string, title?: string) => void;
}

export function ProjectSessionsModal({ isOpen, onClose, cwd, onSelectSession }: ProjectSessionsModalProps) {
  const { t } = useTranslation();
  const [sessions, setSessions] = useState<SessionInfo[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [searchKeyword, setSearchKeyword] = useState('');
  const searchInputRef = useRef<HTMLInputElement>(null);

  // Load the session list for the current project
  const loadSessions = useCallback(async () => {
    if (!cwd) return;

    setIsLoading(true);
    setError(null);

    // Encode cwd as directory name format
    const encodedPath = cwd.replace(/\//g, '-');
    const exit = await BrowserRuntime.runPromiseExit(loadSessionsByProject<SessionInfo>(encodedPath));
    if (exit._tag === 'Success') {
      setSessions(exit.value as SessionInfo[]);
    } else {
      setError('Failed to load sessions');
    }
    setIsLoading(false);
  }, [cwd]);

  useEffect(() => {
    if (isOpen) {
      loadSessions();
      // Auto-focus the search input
      setTimeout(() => {
        searchInputRef.current?.focus();
      }, 100);
    }
  }, [isOpen, loadSessions]);

  // Close on ESC key
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && isOpen) {
        onClose();
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, onClose]);

  const handleSessionClick = (session: SessionInfo) => {
    // Extract sessionId from sessionPath (filename without .jsonl)
    const fileName = session.path.split('/').pop() || '';
    const sessionId = fileName.replace('.jsonl', '');

    if (onSelectSession) {
      // Use onSelectSession callback if provided (adds a new tab in TabManager)
      onSelectSession(sessionId, session.title);
      onClose();
    } else {
      // Otherwise notify parent Workspace to open
      publishTopic(Topics.OpenProject, { cwd, sessionId });
    }
  };

  const formatDate = (isoString: string) => {
    const date = new Date(isoString);
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    });
  };

  // Match against the server-built full-text corpus (title + summary + every
  // user message, untruncated) so search isn't limited by the truncated,
  // 5+5-sampled display fields. Falls back to display fields for older payloads.
  const filteredSessions = sessions.filter((session) => {
    if (!searchKeyword) return true;
    const keyword = searchKeyword.toLowerCase();
    if (session.searchText !== undefined) {
      return session.searchText.includes(keyword);
    }
    return (
      session.title.toLowerCase().includes(keyword) ||
      session.firstMessages.some((msg) => msg.toLowerCase().includes(keyword)) ||
      session.lastMessages.some((msg) => msg.toLowerCase().includes(keyword))
    );
  });

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      {/* Backdrop */}
      <div
        className="absolute inset-0 bg-black/50 backdrop-blur-sm"
        onClick={onClose}
      />

      {/* Modal */}
      <div className="relative w-full max-w-7xl h-[90vh] mx-4 bg-card rounded-lg shadow-xl flex flex-col overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-3 border-b border-border">
          <div className="flex-1 min-w-0">
            <h2 className="text-sm font-medium text-foreground">
              {t('sessions.sessionList')}
            </h2>
            <p className="text-xs text-muted-foreground truncate" title={cwd}>
              {cwd}
            </p>
          </div>
          <div className="flex items-center gap-3 ml-4">
            <input
              ref={searchInputRef}
              type="text"
              placeholder={t('sessions.searchSessions')}
              value={searchKeyword}
              onChange={(e) => setSearchKeyword(e.target.value)}
              className="px-2 py-1 text-xs border border-border rounded bg-card text-foreground placeholder-slate-9 focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent"
            />
            <button
              onClick={onClose}
              className="p-1 text-slate-9 hover:text-foreground hover:bg-accent rounded transition-colors"
            >
              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          </div>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-4">
          {isLoading && (
            <div className="flex items-center justify-center h-full">
              <div className="flex items-center gap-2 text-xs text-muted-foreground">
                <svg className="animate-spin h-4 w-4" fill="none" viewBox="0 0 24 24">
                  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                  <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
                </svg>
                <span>{t('sessions.loadingSessions')}</span>
              </div>
            </div>
          )}

          {error && (
            <div className="flex items-center justify-center h-full">
              <div className="text-xs text-red-11">{error}</div>
            </div>
          )}

          {!isLoading && !error && filteredSessions.length === 0 && (
            <div className="flex items-center justify-center h-full">
              <div className="text-xs text-muted-foreground">
                {searchKeyword ? t('sessions.noMatchingSessions') : t('sessions.noSessionsYet')}
              </div>
            </div>
          )}

          {!isLoading && !error && filteredSessions.length > 0 && (
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
              {filteredSessions.map((session) => (
                <div
                  key={session.path}
                  onClick={() => handleSessionClick(session)}
                  className="p-3 bg-secondary rounded border border-border hover:border-brand hover:shadow-md cursor-pointer transition-all"
                >
                  {/* Session Title + Engine Badge */}
                  <div className="flex items-center gap-1.5 mb-1">
                    {session.engine && session.engine !== 'claude' && (
                      <span className={`shrink-0 px-1 py-0.5 text-[10px] leading-none font-medium rounded ${
                        session.engine === 'claude2' ? 'bg-orange-500/15 text-orange-11' :
                        session.engine === 'ollama' ? 'bg-blue-500/15 text-blue-11' :
                        session.engine === 'codex' ? 'bg-green-500/15 text-green-11' :
                        session.engine === 'kimi' ? 'bg-purple-500/15 text-purple-11' :
                        'bg-muted text-muted-foreground'
                      }`}>
                        {session.engine}
                      </span>
                    )}
                    <h4 className="text-xs font-medium text-foreground truncate" title={session.title}>
                      {session.title}
                    </h4>
                  </div>

                  {/* Session Time */}
                  <div className="text-xs text-muted-foreground mb-2">
                    {formatDate(session.modifiedAt)}
                  </div>

                  {/* Messages Preview */}
                  <div className="space-y-0.5 text-xs">
                    {/* First Messages */}
                    {session.firstMessages.map((msg, idx) => (
                      <div
                        key={`first-${idx}`}
                        className="text-foreground truncate"
                        title={msg}
                      >
                        <span className="text-slate-9 mr-1">•</span>
                        {msg}
                      </div>
                    ))}

                    {/* Separator if there are last messages */}
                    {session.lastMessages.length > 0 && (
                      <div className="text-slate-9 text-center py-0.5">
                        ···
                      </div>
                    )}

                    {/* Last Messages */}
                    {session.lastMessages.map((msg, idx) => (
                      <div
                        key={`last-${idx}`}
                        className="text-foreground truncate"
                        title={msg}
                      >
                        <span className="text-slate-9 mr-1">•</span>
                        {msg}
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
