import { useState, useEffect } from "react";
import {
  Upload,
  Trash2,
  FileText,
  Check,
  Loader2,
  Database,
  X,
} from "lucide-react";
import {
  getDocuments,
  uploadDocument,
  processDocument,
  deleteDocument,
  type ApiDocument,
  type DocumentStatus,
} from "../../services/api";

interface KnowledgeManagementProps {
  open: boolean;
  onClose: () => void;
}

const getUserId = (): string | null => {
  const stored = localStorage.getItem("chatbot_user");
  if (!stored) return null;
  return (JSON.parse(stored).user_id as string) ?? null;
};

export default function KnowledgeManagement({
  open,
  onClose,
}: KnowledgeManagementProps) {
  const [documents, setDocuments] = useState<ApiDocument[]>([]);
  const [loadingDocs, setLoadingDocs] = useState(false);
  const [docsError, setDocsError] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState<string | null>(null);
  const [processing, setProcessing] = useState<string | null>(null);
  const [deleting, setDeleting] = useState<string | null>(null);

  useEffect(() => {
    if (!open) return;
    const userId = getUserId();
    if (!userId) return;
    loadDocuments(userId);
  }, [open]);

  const loadDocuments = async (userId: string) => {
    setLoadingDocs(true);
    setDocsError(null);
    try {
      setDocuments(await getDocuments(userId));
    } catch (err) {
      setDocsError(
        err instanceof Error ? err.message : "Failed to load documents"
      );
    } finally {
      setLoadingDocs(false);
    }
  };

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files || files.length === 0) return;
    const userId = getUserId();
    if (!userId) return;

    setUploading(true);
    setUploadError(null);

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      try {
        const uploadRes = await uploadDocument(userId, file);
        const newDoc: ApiDocument = {
          id: uploadRes.data.id,
          filename: uploadRes.data.filename,
          status: "pending",
          file_size: file.size,
          file_type: file.name.split(".").pop() ?? "",
          created_at: new Date().toISOString(),
        };
        setDocuments((prev) => [newDoc, ...prev]);

        await processDocumentById(userId, uploadRes.data.id);
      } catch (err) {
        setUploadError(err instanceof Error ? err.message : "Upload failed");
      }
    }

    setUploading(false);
    e.target.value = "";
  };

  const processDocumentById = async (userId: string, docId: string) => {
    setProcessing(docId);
    setDocuments((prev) =>
      prev.map((d) =>
        d.id === docId ? { ...d, status: "processing" as DocumentStatus } : d
      )
    );
    try {
      await processDocument(userId, docId);
      setDocuments((prev) =>
        prev.map((d) =>
          d.id === docId ? { ...d, status: "completed" as DocumentStatus } : d
        )
      );
    } catch {
      setDocuments((prev) =>
        prev.map((d) =>
          d.id === docId ? { ...d, status: "failed" as DocumentStatus } : d
        )
      );
    } finally {
      setProcessing(null);
    }
  };

  const handleDeleteDocument = async (docId: string) => {
    const userId = getUserId();
    if (!userId) return;
    setDeleting(docId);
    try {
      await deleteDocument(userId, docId);
      setDocuments((prev) => prev.filter((d) => d.id !== docId));
    } catch (err) {
      console.error("Delete failed:", err);
    } finally {
      setDeleting(null);
    }
  };

  const deleteAllDocuments = async () => {
    if (!window.confirm("Are you sure you want to delete all documents?"))
      return;
    const userId = getUserId();
    if (!userId) return;
    for (const doc of documents) {
      try {
        await deleteDocument(userId, doc.id);
      } catch {
        // continue deleting others
      }
    }
    setDocuments([]);
  };

  const formatFileSize = (bytes: number) => {
    if (bytes < 1024) return bytes + " B";
    if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + " KB";
    return (bytes / (1024 * 1024)).toFixed(2) + " MB";
  };

  const formatDate = (isoString: string) => {
    return new Date(isoString).toLocaleString();
  };

  const renderStatus = (doc: ApiDocument) => {
    if (doc.status === "completed") {
      return (
        <div className="flex items-center gap-1.5 text-green-600">
          <Check className="w-3.5 h-3.5" />
          <span className="text-xs font-medium">Processed</span>
        </div>
      );
    }

    if (doc.status === "processing" || processing === doc.id) {
      return (
        <div className="flex items-center gap-1.5 text-blue-600">
          <Loader2 className="w-3.5 h-3.5 animate-spin" />
          <span className="text-xs">Processing...</span>
        </div>
      );
    }

    // pending or failed
    return (
      <button
        onClick={() => {
          const userId = getUserId();
          if (userId) processDocumentById(userId, doc.id);
        }}
        disabled={processing === doc.id}
        className="flex items-center gap-1.5 bg-gradient-to-r from-[#00C853] to-[#00A843] text-white px-3 py-1.5 rounded-lg hover:from-[#00A843] hover:to-[#00962B] transition disabled:opacity-50 disabled:cursor-not-allowed text-xs"
      >
        <Database className="w-3.5 h-3.5" />
        {doc.status === "failed" ? "Retry Process" : "Process to Knowledge"}
      </button>
    );
  };

  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
      <div className="bg-white rounded-xl shadow-2xl w-full max-w-4xl max-h-[90vh] flex flex-col m-4">
        {/* Header */}
        <div className="flex items-center justify-between p-4 border-b border-slate-200 bg-gradient-to-r from-[#FF8F00] to-[#FF6F00]">
          <div className="flex items-center gap-2">
            <Database className="w-5 h-5 text-white" />
            <h2 className="text-lg text-white">Knowledge Management</h2>
          </div>
          <button
            onClick={onClose}
            className="text-white/80 hover:text-white transition"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-4">
          {/* Upload Section */}
          <div className="mb-4">
            <label
              htmlFor="file-upload"
              className="flex items-center justify-center gap-2 border-2 border-dashed border-slate-300 rounded-lg p-6 cursor-pointer hover:border-[#4FC3F7] hover:bg-slate-50 transition"
            >
              <Upload className="w-5 h-5 text-slate-600" />
              <div className="text-center">
                <p className="text-slate-900 font-medium text-sm">
                  Upload Documents (PDF, DOCX, TXT)
                </p>
                <p className="text-xs text-slate-500 mt-0.5">
                  Click to browse or drag and drop
                </p>
              </div>
              <input
                id="file-upload"
                type="file"
                accept=".pdf,.docx,.txt"
                multiple
                onChange={handleFileUpload}
                className="hidden"
                disabled={uploading}
              />
            </label>
            {uploadError && (
              <p className="mt-2 text-xs text-red-600 bg-red-50 border border-red-200 px-3 py-2 rounded-lg">
                {uploadError}
              </p>
            )}
          </div>

          {/* Documents List */}
          <div className="space-y-2">
            <div className="flex items-center justify-between mb-3">
              <h3 className="text-sm text-slate-900 font-medium">
                Documents ({documents.length})
              </h3>
              {documents.length > 0 && (
                <button
                  onClick={deleteAllDocuments}
                  className="text-xs text-red-600 hover:text-red-700 flex items-center gap-1"
                >
                  <Trash2 className="w-3.5 h-3.5" />
                  Delete All
                </button>
              )}
            </div>

            {loadingDocs ? (
              <div className="flex justify-center py-8">
                <Loader2 className="w-6 h-6 animate-spin text-slate-400" />
              </div>
            ) : docsError ? (
              <p className="text-center text-sm text-red-600 py-4">
                {docsError}
              </p>
            ) : documents.length === 0 ? (
              <div className="text-center py-8">
                <FileText className="w-12 h-12 text-slate-300 mx-auto mb-3" />
                <p className="text-slate-500 text-sm">
                  No documents uploaded yet
                </p>
                <p className="text-xs text-slate-400 mt-1">
                  Upload files to build your knowledge base
                </p>
              </div>
            ) : (
              documents.map((doc) => (
                <div
                  key={doc.id}
                  className="bg-slate-50 rounded-lg p-3 border border-slate-200"
                >
                  <div className="flex items-start gap-3">
                    <FileText className="w-8 h-8 text-red-500 flex-shrink-0 mt-0.5" />
                    <div className="flex-1 min-w-0">
                      <div className="flex items-start justify-between gap-2">
                        <div className="flex-1 min-w-0">
                          <h4 className="text-slate-900 font-medium truncate text-sm">
                            {doc.filename}
                          </h4>
                          <p className="text-xs text-slate-500 mt-0.5">
                            {formatFileSize(doc.file_size)} •{" "}
                            {formatDate(doc.created_at)}
                          </p>
                        </div>
                        <button
                          onClick={() => handleDeleteDocument(doc.id)}
                          disabled={deleting === doc.id}
                          className="text-slate-400 hover:text-red-600 transition flex-shrink-0 disabled:opacity-50"
                          title="Delete document"
                        >
                          {deleting === doc.id ? (
                            <Loader2 className="w-4 h-4 animate-spin" />
                          ) : (
                            <Trash2 className="w-4 h-4" />
                          )}
                        </button>
                      </div>

                      <div className="mt-2 flex items-center gap-2">
                        {renderStatus(doc)}
                      </div>
                    </div>
                  </div>
                </div>
              ))
            )}
          </div>
        </div>

        {/* Footer */}
        <div className="border-t border-slate-200 p-3 bg-slate-50 rounded-b-xl">
          <p className="text-[10px] text-slate-500 text-center">
            Supported formats: PDF, DOCX, TXT
          </p>
        </div>
      </div>
    </div>
  );
}
