import { useState, useRef, useEffect } from "react";
import { useNavigate } from "react-router";
import {
  useGetKBDocuments,
  useUploadKBPdf,
  useDeleteDocument,
  useUploadKBUrl,
} from "app/utils/api";
import { BsLink45Deg, BsChevronLeft, BsFileEarmarkText, BsUpload, BsEye, BsFilePdf } from "react-icons/bs";
import { Modal } from "@shopify/polaris";
import styles from "./datasource.module.css";
import Card from "app/components/ui/card";
import Button from "app/components/ui/button";
import { useGlobalContext } from "../providers/global-context";

export default function DatasourcePage() {
  const [uploadType, setUploadType] = useState<"file" | "url">("file");
  const [uploadValue, setUploadValue] = useState("");
  const [selectedFileName, setSelectedFileName] = useState<string>("");
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [shouldAutoUpload, setShouldAutoUpload] = useState(false);
  const [viewModalOpen, setViewModalOpen] = useState(false);
  const [selectedDocument, setSelectedDocument] = useState<any>(null);

  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const navigate = useNavigate();

  const uploadMutation = useUploadKBPdf();
  const deleteMutation = useDeleteDocument();
  const uploadUrlMutation = useUploadKBUrl();

  const { user } = useGlobalContext()

  // Fetch documents for the single KB from API via shared hook
  const { data: kbDocsResponse, isLoading: kbDocsLoading } = useGetKBDocuments(user?.knowledge_base_id!);

  // combine local docs (uploaded in UI) with API docs
  const apiDocsRaw = (kbDocsResponse && (kbDocsResponse as any).data) || [];
  const apiDocs = apiDocsRaw.map((d: any) => ({
    id: d._id,
    name: d.document_title || d.name,
    type: d.type || (d.url ? "TEXT" : "file"), // Use actual type from API (DOCX, PDF, TEXT)
    content: d.content || null,
    url: d.url || null,
    fromApi: true,
  }));

  const docs = apiDocs;

  // Get icon based on document type
  const getDocumentIcon = (type: string) => {
    switch (type) {
      case "PDF":
        return <BsFilePdf className={styles.docIcon} />;
      case "DOCX":
      case "DOC":
        return <BsFileEarmarkText className={styles.docIcon} />;
      case "TEXT":
        return <BsLink45Deg className={styles.docIcon} />;
      default:
        return <BsFileEarmarkText className={styles.docIcon} />;
    }
  };

  // Filter documents based on selected upload type
  const filteredDocs = docs.filter((doc: any) => {
    if (uploadType === "file") {
      // File tab shows DOCX, PDF, etc. (not TEXT which is for URLs)
      return doc.type !== "TEXT";
    } else {
      // URL tab shows only TEXT type (URLs)
      return doc.type === "TEXT";
    }
  });

  // Handle view document
  const handleViewDocument = (doc: any) => {
    setSelectedDocument(doc);
    setViewModalOpen(true);
  };

  const handleCloseViewModal = () => {
    setViewModalOpen(false);
    setSelectedDocument(null);
  };

  // central delete handler (separate from JSX)
  const handleDelete = async (doc: {
    id: string;
    name: string;
    type: string;
    fromApi?: boolean;
  }) => {
    // if document is from API, call delete endpoint
    if ((doc as any).fromApi) {
      try {
        await deleteMutation.mutateAsync({ id: doc.id, kbId: user?.knowledge_base_id! });
        // server-side deletion will cause cache invalidation via the hook
      } catch (err) {
        console.error("Failed to delete document", err);
      }
    }
  };

  // Handle URL upload
  const handleUpload = async () => {
    if (!uploadValue) return;
    
    try {
      await uploadUrlMutation.mutateAsync({
        url: uploadValue,
        knowledge_base_id: user?.knowledge_base_id!,
        depth: 1,
      });
      setUploadValue("");
    } catch (err) {
      console.error("URL upload failed", err);
    }
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files || files.length === 0) return;
    const file = files[0];
    // stage selected file for upload
    setSelectedFile(file);
    setSelectedFileName(file.name);
    // reset input so same file can be chosen again if needed
    e.currentTarget.value = "";
    
    // Auto-upload immediately regardless of document count
    setShouldAutoUpload(true);
  };

  const handleChooseFile = () => {
    // open native file picker
    fileInputRef.current?.click();
  };

  // Drag and drop handlers
  const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(true);
  };

  const handleDragLeave = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);
  };

  const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
  };

  const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragging(false);

    const files = e.dataTransfer.files;
    if (files && files.length > 0) {
      const file = files[0];
      setSelectedFile(file);
      setSelectedFileName(file.name);
      
      // Auto-upload immediately regardless of document count
      setShouldAutoUpload(true);
    }
  };

  // central upload handler (separate from JSX)
  const handleUploadFile = async () => {
    if (!selectedFile) return;
    
    // Simulate upload progress
    setUploadProgress(0);
    const progressInterval = setInterval(() => {
      setUploadProgress((prev) => {
        if (prev >= 90) {
          clearInterval(progressInterval);
          return 90;
        }
        return prev + 10;
      });
    }, 200);

    try {
      const res = await uploadMutation.mutateAsync({
        knowledge_base_id: user?.knowledge_base_id!,
        file: selectedFile,
      });
      
      // Complete the progress
      clearInterval(progressInterval);
      setUploadProgress(100);
      
      // Wait a bit to show 100% before clearing
      setTimeout(() => {
        setSelectedFile(null);
        setSelectedFileName("");
        setUploadProgress(0);
      }, 500);
      
    } catch (err) {
      clearInterval(progressInterval);
      setUploadProgress(0);
      console.error("Upload failed", err);
    }
  };

  // Auto-upload effect when file is selected in empty state
  useEffect(() => {
    if (shouldAutoUpload && selectedFile) {
      setShouldAutoUpload(false);
      handleUploadFile();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [shouldAutoUpload, selectedFile]);

  return (
    <div className={styles.container}>
      <div className={styles.headerRow}>
        <button
          onClick={() => navigate("/app/aiassistant")}
          className={styles.backButton}
          aria-label="Back"
        >
          <BsChevronLeft size={18} />
          <span>Back</span>
        </button>
        <h1 className={styles.title}>Data Sources</h1>
      </div>

      <div className={styles.singleColumnLayout}>
        <Card>
          <div className={styles.cardHeader}>
            <h3 className={styles.cardTitle}>Documents</h3>
            <div className={styles.uploadToggle}>
              <label className={styles.uploadLabel}>
                <input
                  type="radio"
                  name="upload"
                  checked={uploadType === "file"}
                  onChange={() => setUploadType("file")}
                />
                <span>File</span>
              </label>
              <label className={styles.uploadLabel}>
                <input
                  type="radio"
                  name="upload"
                  checked={uploadType === "url"}
                  onChange={() => setUploadType("url")}
                />
                <span>URL</span>
              </label>
            </div>
          </div>

            <div className={styles.uploadArea}>
              {uploadType === "file" ? (
                <>
                  {filteredDocs.length === 0 ? (
                    // Empty state for files - unified with drag and drop
                    <div 
                      className={`${styles.dropZone} ${isDragging ? styles.dragging : ""} ${uploadMutation.isPending ? styles.uploading : ""}`}
                      onDragEnter={handleDragEnter}
                      onDragOver={handleDragOver}
                      onDragLeave={handleDragLeave}
                      onDrop={handleDrop}
                      onClick={!uploadMutation.isPending ? handleChooseFile : undefined}
                      style={{ cursor: uploadMutation.isPending ? 'not-allowed' : 'pointer' }}
                    >
                      <input
                        ref={fileInputRef}
                        id="file-upload"
                        className={styles.fileInput}
                        type="file"
                        onChange={handleFileChange}
                        disabled={uploadMutation.isPending}
                      />
                      
                      {uploadMutation.isPending ? (
                        <>
                          <div className={styles.dropZoneIcon}>
                            <BsFileEarmarkText size={48} />
                          </div>
                          <div className={styles.dropZoneTitle}>Uploading file...</div>
                          <div className={styles.selectedFileName} style={{ marginBottom: '16px' }}>
                            {selectedFileName}
                          </div>
                          <div className={styles.progressBar}>
                            <div 
                              className={styles.progressBarFill} 
                              style={{ width: `${uploadProgress}%` }}
                            />
                          </div>
                          <div className={styles.progressText}>{uploadProgress}%</div>
                        </>
                      ) : (
                        <>
                          <div className={styles.dropZoneIcon}>
                            <BsUpload size={48} />
                          </div>
                          <div className={styles.dropZoneTitle}>
                            {isDragging ? "Drop your file here" : "No documents yet"}
                          </div>
                          <div className={styles.dropZoneSubtitle}>
                            {isDragging ? "Release to upload" : "Drag & drop files here or click to browse"}
                          </div>
                          <div className={styles.dropZoneText}>
                            Upload files to populate this knowledge base. Documents will be searchable by your assistant.
                          </div>
                          <div className={styles.dropZoneHint}>
                            Supports PDF, DOC, DOCX, TXT files
                          </div>
                        </>
                      )}
                    </div>
                  ) : (
                    // Has documents - show compact drag and drop + document list
                    <>
                      <div 
                        className={`${styles.dropZone} ${styles.compact} ${isDragging ? styles.dragging : ""} ${selectedFile ? styles.hasFile : ""} ${uploadMutation.isPending ? styles.uploading : ""}`}
                        onDragEnter={handleDragEnter}
                        onDragOver={handleDragOver}
                        onDragLeave={handleDragLeave}
                        onDrop={handleDrop}
                        onClick={!uploadMutation.isPending ? handleChooseFile : undefined}
                        style={{ cursor: uploadMutation.isPending ? 'not-allowed' : 'pointer' }}
                      >
                        <input
                          ref={fileInputRef}
                          id="file-upload"
                          className={styles.fileInput}
                          type="file"
                          onChange={handleFileChange}
                          disabled={uploadMutation.isPending}
                        />
                        
                        {uploadMutation.isPending ? (
                          <>
                            <div className={styles.dropZoneIconSmall}>
                              <BsFileEarmarkText size={24} />
                            </div>
                            <div className={styles.selectedFileInfo}>
                              <div className={styles.selectedFileName}>{selectedFileName}</div>
                              <div className={styles.selectedFileHint}>Uploading...</div>
                            </div>
                            <div className={styles.progressBar}>
                              <div 
                                className={styles.progressBarFill} 
                                style={{ width: `${uploadProgress}%` }}
                              />
                            </div>
                            <div className={styles.progressText}>{uploadProgress}%</div>
                          </>
                        ) : !selectedFile ? (
                          <>
                            <div className={styles.dropZoneIcon}>
                              <BsUpload size={32} />
                            </div>
                            <div className={styles.dropZoneTitle}>
                              {isDragging ? "Drop your file here" : "Drag & drop file here"}
                            </div>
                            <div className={styles.dropZoneSubtitle}>
                              or click to browse
                            </div>
                          </>
                        ) : (
                          <>
                            <div className={styles.dropZoneIconSmall}>
                              <BsFileEarmarkText size={24} />
                            </div>
                            <div className={styles.selectedFileInfo}>
                              <div className={styles.selectedFileName}>{selectedFileName}</div>
                              <div className={styles.selectedFileHint}>Click to change file</div>
                            </div>
                            <div className={styles.uploadButtonWrapper}>
                              <Button
                                btnVariant="primary"
                                btnSize="small"
                                isLoading={uploadMutation.isPending}
                                disabled={uploadMutation.isPending}
                                onClick={(e) => {
                                  e.stopPropagation();
                                  handleUploadFile();
                                }}
                              >
                                {uploadMutation.isPending ? "Uploading..." : "Upload"}
                              </Button>
                            </div>
                          </>
                        )}
                      </div>

                      <div className={styles.docsList}>
                        {filteredDocs.map((doc: { id: string; name: string; type: string; content?: string; url?: string }) => (
                          <div key={doc.id} className={styles.docItem}>
                            <div className={styles.docMeta}>
                              {getDocumentIcon(doc.type)}
                              <div>
                                <div className={styles.docName}>{doc.name}</div>
                                <div className={styles.docType}>{doc.type.toUpperCase()}</div>
                              </div>
                            </div>
                            <div className={styles.docActions}>
                              <Button
                                btnVariant="secondary"
                                btnSize="small"
                                onClick={() => handleViewDocument(doc)}
                              >
                                <BsEye size={16} />
                              </Button>
                              <Button
                                btnVariant="secondary"
                                btnSize="small"
                                onClick={() => handleDelete(doc)}
                              >
                                Delete
                              </Button>
                            </div>
                          </div>
                        ))}
                      </div>
                    </>
                  )}
                </>
              ) : (
                // URL Tab
                <>
                  <div className={styles.fileRow}>
                    <input
                      type="text"
                      placeholder="https://example.com/article"
                      value={uploadValue}
                      onChange={(e) => setUploadValue(e.target.value)}
                      className={styles.urlInput}
                      disabled={uploadUrlMutation.isPending}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter' && uploadValue) {
                          handleUpload();
                        }
                      }}
                    />
                    <Button
                      btnVariant="primary"
                      btnSize="small"
                      onClick={handleUpload}
                      disabled={!uploadValue || uploadUrlMutation.isPending}
                      isLoading={uploadUrlMutation.isPending}
                    >
                      {uploadUrlMutation.isPending ? "Adding..." : "Add URL"}
                    </Button>
                  </div>

                  <div className={styles.docsList}>
                    {filteredDocs.length === 0 ? (
                      <div className={styles.emptyState}>
                        <div className={styles.emptyIcon}>
                          <BsLink45Deg size={48} />
                        </div>
                        <div className={styles.emptyTitle}>No URLs added yet</div>
                        <div className={styles.emptyText}>
                          Add website URLs to your knowledge base. Content from these pages will be indexed and searchable by your assistant.
                        </div>
                      </div>
                    ) : (
                      filteredDocs.map((doc: { id: string; name: string; type: string; content?: string; url?: string }) => (
                        <div key={doc.id} className={styles.docItem}>
                          <div className={styles.docMeta}>
                            {getDocumentIcon(doc.type)}
                            <div>
                              <div className={styles.docName}>{doc.name}</div>
                              <div className={styles.docType}>{doc.type.toUpperCase()}</div>
                            </div>
                          </div>
                          <div className={styles.docActions}>
                            <Button
                              btnVariant="secondary"
                              btnSize="small"
                              onClick={() => handleViewDocument(doc)}
                            >
                              <BsEye size={16} />
                            </Button>
                            <Button
                              btnVariant="secondary"
                              btnSize="small"
                              onClick={() => handleDelete(doc)}
                            >
                              Delete
                            </Button>
                          </div>
                        </div>
                      ))
                    )}
                  </div>
                </>
              )}
            </div>
          </Card>
      </div>

      {/* View Document Modal */}
      <Modal
        open={viewModalOpen}
        onClose={handleCloseViewModal}
        title={selectedDocument?.name || "Document Content"}
        size="large"
      >
        <Modal.Section>
          {selectedDocument?.content ? (
            <div className={styles.documentContent}>
              <pre>{selectedDocument.content}</pre>
            </div>
          ) : selectedDocument?.url ? (
            <div className={styles.documentContent}>
              <p><strong>URL:</strong> <a href={selectedDocument.url} target="_blank" rel="noopener noreferrer">{selectedDocument.url}</a></p>
              <p className={styles.noContentMessage}>This is a URL document. Click the link above to visit the page.</p>
            </div>
          ) : (
            <div className={styles.documentContent}>
              <p className={styles.noContentMessage}>No content available for this document.</p>
            </div>
          )}
        </Modal.Section>
      </Modal>
    </div>
  );
}
