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 "../../../components/datasource/datasource.module.css";
import Card from "app/components/ui/card";
import Button from "app/components/ui/button";
import { useGlobalContext } from "app/components/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();

  const { data: kbDocsResponse, isLoading: kbDocsLoading } = useGetKBDocuments(user?.knowledge_base_id!);

  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"),
    content: d.content || null,
    url: d.url || null,
    fromApi: true,
  }));

  const docs = apiDocs;

  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} />;
    }
  };

  const filteredDocs = docs.filter((doc: any) => {
    if (uploadType === "file") {
      return doc.type !== "TEXT";
    } else {
      return doc.type === "TEXT";
    }
  });

  const handleViewDocument = (doc: any) => {
    setSelectedDocument(doc);
    setViewModalOpen(true);
  };

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

  const handleDelete = async (doc: { id: string; name: string; type: string; fromApi?: boolean }) => {
    if ((doc as any).fromApi) {
      try {
        await deleteMutation.mutateAsync({ id: doc.id, kbId: user?.knowledge_base_id! });
      } catch (err) {
        console.error("Failed to delete document", err);
      }
    }
  };

  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];
    setSelectedFile(file);
    setSelectedFileName(file.name);
    e.currentTarget.value = "";
    setShouldAutoUpload(true);
  };

  const handleChooseFile = () => {
    fileInputRef.current?.click();
  };

  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);
      setShouldAutoUpload(true);
    }
  };

  const handleUploadFile = async () => {
    if (!selectedFile) return;
    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,
      });
      clearInterval(progressInterval);
      setUploadProgress(100);
      setTimeout(() => {
        setSelectedFile(null);
        setSelectedFileName("");
        setUploadProgress(0);
      }, 500);
    } catch (err) {
      clearInterval(progressInterval);
      setUploadProgress(0);
      console.error("Upload failed", err);
    }
  };

  useEffect(() => {
    if (shouldAutoUpload && selectedFile) {
      setShouldAutoUpload(false);
      handleUploadFile();
    }
  }, [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 ? (
                  <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>
                ) : (
                  <>
                    <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>
                  </>
                )}
              </>
            ) : (
              <>
                <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>

      <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>
  );
}
