"use client";

import React, { useState } from "react";
import { Form, FloatingLabel, Accordion, Card, Button } from "react-bootstrap";
import { FileTypes, EventTypes } from "@/lib/types";
import { useToast } from "@/context/ToastContext";
import Masonry, { ResponsiveMasonry } from "react-responsive-masonry";
import Lightbox from "yet-another-react-lightbox";
import Counter from "yet-another-react-lightbox/plugins/counter";
import Fullscreen from "yet-another-react-lightbox/plugins/fullscreen";
import Slideshow from "yet-another-react-lightbox/plugins/slideshow";
import Zoom from "yet-another-react-lightbox/plugins/zoom";
import Thumbnails from "yet-another-react-lightbox/plugins/thumbnails";
import "yet-another-react-lightbox/styles.css";
import "yet-another-react-lightbox/plugins/counter.css";
import "yet-another-react-lightbox/plugins/thumbnails.css";

type Props = {
  event: EventTypes;
  setEvents: React.Dispatch<React.SetStateAction<EventTypes[]>>;
};

export default function UploadEvent({ event, setEvents }: Props) {
  const { showToast } = useToast();

  const [open, setOpen] = useState(false);
  const [currentIndex, setCurrentIndex] = useState(0);

  // Split event files into images & videos
  const images = event.se_files.filter((f) => f.up_file_type.startsWith("image/"));
  const videos = event.se_files.filter((f) => f.up_file_type.startsWith("video/"));

  const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (!files) return;

    for (const file of Array.from(files)) {
      const formData = new FormData();
      formData.append("up_file", file);
      formData.append("up_s_id", event.se_id.toString());
      formData.append("up_s_type", "EventFiles");

      try {
        const res = await fetch("/api/events/upload", { method: "POST", body: formData });
        const result = await res.json();

        if (res.ok && result.fileInfo) {
          showToast(`${file.name} uploaded successfully.`, "success");

          const newFile: FileTypes = {
            up_id: result.fileInfo.up_id,
            up_fname: result.fileInfo.fileName,
            up_oname: result.fileInfo.originalName,
            up_ext: result.fileInfo.ext,
            up_file_type: result.fileInfo.mime,
            up_size: result.fileInfo.size,
            up_width: result.fileInfo.width,
            up_height: result.fileInfo.height,
            src: result.fileInfo.path,
          };

          setEvents((prev) =>
            prev.map((ev) =>
              ev.se_id === event.se_id ? { ...ev, se_files: [...ev.se_files, newFile] } : ev
            )
          );
        } else {
          showToast(`${file.name} failed: ${result.error}`, "danger");
        }
      } catch {
        showToast(`${file.name} upload error.`, "danger");
      }
    }
    e.target.value = "";
  };
  const handleDelete = async (fileId: number) => {
    if (!confirm("Are you sure you want to delete this file?")) return;

    try {
      const res = await fetch("/api/events/delete", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ fileId }),
      });

      if (res.ok) {
        setEvents((prev) =>
          prev.map((ev) =>
            ev.se_id === event.se_id
              ? { ...ev, se_files: ev.se_files.filter((f) => f.up_id !== fileId) }
              : ev
          )
        );
        showToast("File deleted.", "success");
      } else {
        const { error } = await res.json();
        showToast(error || "Failed to delete file.", "danger");
      }
    } catch {
      showToast("Error deleting file.", "danger");
    }
  };

  const handleSetCover = async (fileId: number) => {
    try {
      const res = await fetch("/api/events/cover", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ eventId: event.se_id, fileId }),
      });
      const data = await res.json();
      if (res.ok) {
        setEvents((prev) =>
          prev.map((ev) =>
            ev.se_id === event.se_id
              ? { ...ev, se_up_id: data.se_up_id, se_cover: data.se_cover }
              : ev
          )
        );
        showToast("Cover image updated!", "success");
      } else {
        const { error } = await res.json();
        showToast(error || "Failed to set cover.", "danger");
      }
    } catch {
      showToast("Error setting cover.", "danger");
    }
  };

  return (
    <Accordion flush>
      <Accordion.Item eventKey="0">
        <Accordion.Header>
          Uploaded Files ({event.se_files?.length || 0})
        </Accordion.Header>
        <Accordion.Body>
          <Form.Group controlId={`upload-${event.se_id}`} className="bg-secondary-subtle p-3 rounded-3 mb-3">
            <FloatingLabel label="Upload Multiple Files">
              <Form.Control type="file" multiple accept="image/webp,image/jpeg,image/png,image/jpg,video/mp4,.webp,.jpg,.jpeg,.png,.mp4" onChange={handleUpload} />
            </FloatingLabel>
          </Form.Group>
          {event.se_files && event.se_files.length > 0 ? (
            <ResponsiveMasonry columnsCountBreakPoints={{ 350: 1, 750: 2, 900: 3, 1200: 4 }}>
              <Masonry gutter="10px">
                {videos.map((file) => {
                  const poster = file.src.replace(/\.\w+$/, ".webp"); // optional: if you generate thumbnails
                  return (
                    <Card key={file.up_id} className="rounded-4 border-0 overflow-hidden">
                      <Card.Header className="fs-small">{file.up_oname}</Card.Header>
                      <video controls preload="metadata" poster={poster} className="w-100">
                        <source src={file.src} type={file.up_file_type} />
                        Your browser does not support the video tag.
                      </video>
                      <Card.Footer>
                        <Button variant="outline-danger" className="rounded-pill w-100" onClick={() => handleDelete(file.up_id)}>
                          <i className="bi bi-trash"></i>
                        </Button>                        
                      </Card.Footer>
                    </Card>
                  );
                })}
                {images.map((file, idx) => (
                  <Card key={file.up_id} className="rounded-4 border-0 overflow-hidden">
                    <Card.Header className="fs-small">{file.up_oname}</Card.Header>
                    <Card.Img className="img-fluid rounded-0" src={file.src} alt={file.up_oname} width={file.up_width} height={file.up_height} onClick={() => {setCurrentIndex(idx);setOpen(true);}}/>
                    <Card.Footer className="d-flex gap-2">                      
                      <Button variant="outline-dark" className="rounded-pill w-100" onClick={() => {setCurrentIndex(idx);setOpen(true);}}>
                        <i className="bi bi-zoom-in"></i>
                      </Button>
                      <Button variant={event.se_up_id === file.up_id ? "primary" : "outline-primary"} className="rounded-pill w-100" onClick={() => handleSetCover(file.up_id)}>
                        <i className="bi bi-star-fill"></i>
                      </Button>
                      <Button variant="outline-danger" className="rounded-pill w-100" onClick={() => handleDelete(file.up_id)}>
                        <i className="bi bi-trash"></i>
                      </Button>
                    </Card.Footer>
                  </Card>
                ))}
              </Masonry>
            </ResponsiveMasonry>
          ) : (
            <p className="text-muted small">No files uploaded yet.</p>
          )}
          <Lightbox open={open} close={() => setOpen(false)} slides={images.map((f) => ({ src: f.src }))} index={currentIndex} plugins={[Counter, Fullscreen, Slideshow, Zoom, Thumbnails]} />
        </Accordion.Body>
      </Accordion.Item>
    </Accordion>
  );
}
