/**
 * KnowledgeTab — Qdrant-backed knowledge entry list with pagination and preview.
 *
 * Works with KnowledgeEntry domain entities via application mapper layer.
 * Components never access raw Qdrant payloads.
 *
 * (c) 2026 TWWIM UG. All rights reserved. (www.twwim.com)
 */

import { useState } from 'react';
import {
  FileText, Trash2, Plus, Search, X, Upload, AlertCircle,
  Database, ShieldAlert, ChevronLeft, ChevronRight, Eye,
} from 'lucide-react';
import { useKnowledgeEntries, useCreateKnowledgeEntry, useDeleteKnowledgeEntry } from '../hooks';
import { useTranslation } from '@/i18n/TranslationProvider';
import { tokenStorage } from '@/infrastructure/storage/LocalTokenStorage';
import { EntryPreviewModal } from './EntryPreviewModal';
import { KnowledgeEntry, KnowledgeEntryType, KnowledgeSource } from '@/domain/entities/KnowledgeEntry';
import type { CreateEntryInput } from '@/infrastructure/http/api/knowledge';

const TYPE_COLORS: Record<string, { bg: string; text: string }> = {
  [KnowledgeEntryType.PRODUCT]: { bg: 'bg-blue-100', text: 'text-blue-800' },
  [KnowledgeEntryType.PAGE]: { bg: 'bg-green-100', text: 'text-green-800' },
  [KnowledgeEntryType.DOCUMENT]: { bg: 'bg-purple-100', text: 'text-purple-800' },
  [KnowledgeEntryType.FAQ]: { bg: 'bg-amber-100', text: 'text-amber-800' },
  [KnowledgeEntryType.CUSTOM]: { bg: 'bg-gray-100', text: 'text-gray-800' },
};

const SOURCE_COLORS: Record<string, { bg: string; text: string }> = {
  [KnowledgeSource.WORDPRESS]: { bg: 'bg-indigo-100', text: 'text-indigo-800' },
  [KnowledgeSource.SHOPIFY]: { bg: 'bg-green-100', text: 'text-green-800' },
  [KnowledgeSource.MANUAL]: { bg: 'bg-gray-100', text: 'text-gray-700' },
};

function TypeBadge({ type }: { type: string }) {
  const colors = TYPE_COLORS[type] || TYPE_COLORS[KnowledgeEntryType.CUSTOM];
  return (
    <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${colors.bg} ${colors.text}`}>
      {type}
    </span>
  );
}

function SourceBadge({ source }: { source: string }) {
  const colors = SOURCE_COLORS[source] || SOURCE_COLORS[KnowledgeSource.MANUAL];
  return (
    <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${colors.bg} ${colors.text}`}>
      {source}
    </span>
  );
}

function AddEntryForm({
  tenantId,
  defaultType,
  onClose,
}: {
  tenantId: string;
  defaultType: CreateEntryInput['type'];
  onClose: () => void;
}) {
  const { t } = useTranslation();
  const createMutation = useCreateKnowledgeEntry(tenantId);
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [url, setUrl] = useState('');
  const [category, setCategory] = useState('');

  const isFaq = defaultType === KnowledgeEntryType.FAQ;

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!title.trim() || !content.trim()) return;
    createMutation.mutate(
      {
        type: defaultType,
        title: title.trim(),
        content: content.trim(),
        ...(!isFaq && url.trim() ? { url: url.trim() } : {}),
        ...(!isFaq && category.trim() ? { category: category.trim() } : {}),
      },
      { onSuccess: () => onClose() },
    );
  };

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-6 mb-6">
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-lg font-semibold text-gray-900">{t('knowledge.addEntry')}</h3>
        <button onClick={onClose} className="p-1 text-gray-400 hover:text-gray-600">
          <X size={20} />
        </button>
      </div>
      <form onSubmit={handleSubmit} className="space-y-4">
        {!isFaq && (
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">{t('knowledge.category')}</label>
            <input
              type="text"
              value={category}
              onChange={(e) => setCategory(e.target.value)}
              placeholder={t('common.optional')}
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none"
            />
          </div>
        )}
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            {isFaq ? t('knowledge.question') : t('knowledge.title')}
          </label>
          <input
            type="text"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder={isFaq ? t('knowledge.questionPlaceholder') : t('knowledge.titlePlaceholder')}
            className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none"
            required
          />
        </div>
        <div>
          <label className="block text-sm font-medium text-gray-700 mb-1">
            {isFaq ? t('knowledge.answer') : t('knowledge.content')}
          </label>
          <textarea
            value={content}
            onChange={(e) => setContent(e.target.value)}
            placeholder={isFaq ? t('knowledge.answerPlaceholder') : t('knowledge.contentPlaceholder')}
            rows={4}
            className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none resize-y"
            required
          />
        </div>
        {!isFaq && (
          <div>
            <label className="block text-sm font-medium text-gray-700 mb-1">URL</label>
            <input
              type="url"
              value={url}
              onChange={(e) => setUrl(e.target.value)}
              placeholder="https://..."
              className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none"
            />
          </div>
        )}
        <div className="flex justify-end gap-3">
          <button type="button" onClick={onClose} className="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50">
            {t('common.cancel')}
          </button>
          <button
            type="submit"
            disabled={createMutation.isPending || !title.trim() || !content.trim()}
            className="px-4 py-2 text-sm font-medium text-white bg-cyan-600 rounded-lg hover:bg-cyan-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
          >
            {createMutation.isPending ? (
              <span className="animate-spin h-4 w-4 border-2 border-white border-t-transparent rounded-full" />
            ) : (
              <Upload size={16} />
            )}
            {t('knowledge.save')}
          </button>
        </div>
        {createMutation.isError && (
          <div className="flex items-center gap-2 p-3 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700">
            <AlertCircle size={16} />
            {createMutation.error?.message || t('knowledge.createError')}
          </div>
        )}
      </form>
    </div>
  );
}

function EntryRow({
  entry,
  tenantId,
  onPreview,
}: {
  entry: KnowledgeEntry;
  tenantId: string;
  onPreview: (entry: KnowledgeEntry) => void;
}) {
  const { t } = useTranslation();
  const deleteMutation = useDeleteKnowledgeEntry(tenantId);
  const [confirmDelete, setConfirmDelete] = useState(false);

  return (
    <tr className="hover:bg-gray-50 transition-colors cursor-pointer" onClick={() => onPreview(entry)}>
      <td className="px-4 py-3">
        <div className="flex items-start gap-2">
          <FileText size={16} className="text-gray-400 mt-0.5 shrink-0" />
          <div className="min-w-0">
            <div className="text-sm font-medium text-gray-900 truncate">
              {entry.title}
              {entry.chunkCount > 1 && (
                <span className="ml-1.5 text-xs text-gray-400 font-normal">({entry.chunkCount} chunks)</span>
              )}
            </div>
            {entry.url && (
              <div className="text-xs text-cyan-600 truncate max-w-md">{entry.url}</div>
            )}
            <div className="text-xs text-gray-500 truncate max-w-md">{entry.preview}</div>
          </div>
        </div>
      </td>
      <td className="px-4 py-3">{entry.type && <TypeBadge type={entry.type} />}</td>
      <td className="px-4 py-3">{entry.source && <SourceBadge source={entry.source} />}</td>
      <td className="px-4 py-3 text-xs text-gray-500">{entry.category || '-'}</td>
      <td className="px-4 py-3 text-right">
        <div className="flex items-center justify-end gap-1">
          <button
            onClick={() => onPreview(entry)}
            className="p-1.5 text-gray-400 hover:text-cyan-600 rounded hover:bg-cyan-50 transition-colors"
            title="Preview"
          >
            <Eye size={14} />
          </button>
          {confirmDelete ? (
            <>
              <button onClick={() => setConfirmDelete(false)} className="px-2 py-1 text-xs text-gray-600 hover:text-gray-800">
                {t('common.cancel')}
              </button>
              <button
                onClick={() => deleteMutation.mutate(entry.id, { onSuccess: () => setConfirmDelete(false) })}
                disabled={deleteMutation.isPending}
                className="px-2 py-1 text-xs text-white bg-red-600 rounded hover:bg-red-700 disabled:opacity-50"
              >
                {deleteMutation.isPending ? '...' : t('common.confirm')}
              </button>
            </>
          ) : (
            <button
              onClick={() => setConfirmDelete(true)}
              className="p-1.5 text-gray-400 hover:text-red-600 rounded hover:bg-red-50 transition-colors"
              title={t('common.delete')}
            >
              <Trash2 size={14} />
            </button>
          )}
        </div>
      </td>
    </tr>
  );
}

interface KnowledgeTabProps {
  tenantId: string;
  typeFilter: CreateEntryInput['type'];
}

const PAGE_SIZE = 25;

export function KnowledgeTab({ tenantId, typeFilter }: KnowledgeTabProps) {
  const { t } = useTranslation();
  const [isAdding, setIsAdding] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [offset, setOffset] = useState<string | undefined>(undefined);
  const [offsetStack, setOffsetStack] = useState<string[]>([]);
  const [previewEntry, setPreviewEntry] = useState<KnowledgeEntry | null>(null);

  const { data, isLoading, error } = useKnowledgeEntries(tenantId, {
    type: typeFilter,
    limit: PAGE_SIZE,
    offset,
  });

  const isCapped = typeFilter === KnowledgeEntryType.DOCUMENT;
  const capValue = tokenStorage.getCapability('knowledge_files_max');
  const maxFiles = capValue ? parseInt(capValue, 10) : 0;
  const featureEnabled = !isCapped || maxFiles > 0;
  const totalEntries = data?.total ?? 0;
  const atLimit = isCapped && (maxFiles <= 0 || totalEntries >= maxFiles);

  const entries = data?.entries ?? [];
  const nextOffset = data?.nextPageOffset ?? null;
  const page = offsetStack.length + 1;
  const totalPages = Math.ceil(totalEntries / PAGE_SIZE);

  const filtered = searchQuery
    ? entries.filter((e) =>
        e.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
        e.text.toLowerCase().includes(searchQuery.toLowerCase()),
      )
    : entries;

  const handleNextPage = () => {
    if (!nextOffset) return;
    setOffsetStack((prev) => [...prev, offset ?? '']);
    setOffset(nextOffset);
  };

  const handlePrevPage = () => {
    setOffsetStack((prev) => {
      const next = [...prev];
      const prevOffset = next.pop();
      setOffset(prevOffset || undefined);
      return next;
    });
  };

  if (isLoading) {
    return (
      <div className="animate-pulse space-y-4 p-6">
        <div className="h-10 bg-gray-200 rounded w-1/3" />
        <div className="h-64 bg-gray-200 rounded" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="p-6">
        <div className="flex items-center gap-2 p-4 bg-red-50 border border-red-200 rounded-lg text-sm text-red-700">
          <AlertCircle size={16} />
          {t('knowledge.loadError')}: {error.message}
        </div>
      </div>
    );
  }

  return (
    <div>
      {!featureEnabled && (
        <div className="mx-6 mt-4 flex items-center gap-2 p-3 bg-gray-100 border border-gray-200 rounded-lg text-sm text-gray-600">
          <ShieldAlert size={16} className="shrink-0" />
          {t('knowledge.featureDisabled')}
        </div>
      )}

      <div className="px-6 py-4 flex items-center gap-3 flex-wrap">
        <div className="flex-1 min-w-[200px] max-w-sm relative">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" size={16} />
          <input
            type="text"
            placeholder={t('knowledge.searchPlaceholder')}
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            className="w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:ring-2 focus:ring-cyan-500 focus:outline-none"
          />
        </div>

        <div className="text-sm text-gray-500">
          {totalEntries} {totalEntries === 1 ? 'entry' : 'entries'}
        </div>

        <button
          onClick={() => setIsAdding(true)}
          disabled={atLimit}
          className="ml-auto px-4 py-2 text-sm font-medium text-white bg-cyan-600 rounded-lg hover:bg-cyan-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
        >
          <Plus size={16} />
          {t('knowledge.addEntry')}
        </button>
      </div>

      {isAdding && !atLimit && (
        <div className="px-6">
          <AddEntryForm tenantId={tenantId} defaultType={typeFilter} onClose={() => setIsAdding(false)} />
        </div>
      )}

      {filtered.length === 0 ? (
        <div className="px-6 py-12 text-center">
          <Database className="mx-auto h-12 w-12 text-gray-300 mb-3" />
          <p className="text-sm text-gray-500 mb-1">{t('knowledge.noEntries')}</p>
          <p className="text-xs text-gray-400">{t('knowledge.noEntriesHint')}</p>
        </div>
      ) : (
        <>
          <div className="overflow-x-auto">
            <table className="w-full">
              <thead className="bg-gray-50 border-y border-gray-200">
                <tr>
                  <th className="px-4 py-2.5 text-left text-xs font-medium text-gray-500 uppercase">{t('knowledge.title')}</th>
                  <th className="px-4 py-2.5 text-left text-xs font-medium text-gray-500 uppercase">{t('knowledge.type')}</th>
                  <th className="px-4 py-2.5 text-left text-xs font-medium text-gray-500 uppercase">Source</th>
                  <th className="px-4 py-2.5 text-left text-xs font-medium text-gray-500 uppercase">{t('knowledge.category')}</th>
                  <th className="px-4 py-2.5 text-right text-xs font-medium text-gray-500 uppercase">{t('common.actions')}</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-gray-200">
                {filtered.map((entry) => (
                  <EntryRow key={entry.id} entry={entry} tenantId={tenantId} onPreview={setPreviewEntry} />
                ))}
              </tbody>
            </table>
          </div>

          {totalPages > 1 && (
            <div className="px-6 py-3 border-t border-gray-200 flex items-center justify-between">
              <button
                onClick={handlePrevPage}
                disabled={page === 1}
                className="inline-flex items-center gap-1 px-3 py-1.5 text-sm text-gray-600 hover:text-gray-900 disabled:opacity-30 disabled:cursor-not-allowed"
              >
                <ChevronLeft size={16} />
                Previous
              </button>
              <span className="text-sm text-gray-500">Page {page} of {totalPages}</span>
              <button
                onClick={handleNextPage}
                disabled={!nextOffset}
                className="inline-flex items-center gap-1 px-3 py-1.5 text-sm text-gray-600 hover:text-gray-900 disabled:opacity-30 disabled:cursor-not-allowed"
              >
                Next
                <ChevronRight size={16} />
              </button>
            </div>
          )}
        </>
      )}

      {previewEntry && (
        <EntryPreviewModal entry={previewEntry} onClose={() => setPreviewEntry(null)} />
      )}
    </div>
  );
}
