"use client";

import React, { useEffect, useState, useCallback } from "react";
import { Container, Row, Col, Card, Form, FloatingLabel, Badge, Button, Stack, Spinner, ListGroup } from "react-bootstrap";
import { useForm, Controller } from "react-hook-form";
import { useToast } from "@/context/ToastContext";
import { excerptFromHtml,unixToDateTime,findValue } from "@/lib/function";
import LoadingCMS from "@/components/LoadingCMS";
import HtmlEditor from "@/components/HtmlEditor";
import { EventCategoryTypes, EventTypes } from "@/lib/types";
import UploadEvent from "@/components/UploadEvents";
import { useRecaptcha } from "@/hooks/useRecaptcha";


export default function Events() {
  const { showToast } = useToast();
  const { getToken } = useRecaptcha();

  const [events, setEvents] = useState<EventTypes[]>([]);
  const [categories, setCategories] = useState<EventCategoryTypes[]>([]);
  const [isLoading, setLoading] = useState(true);
  const [searchEvent, setEventSearch] = useState("");
  const [selectedCategory, setselectedCategory] = useState<number | "">("");
  const [selectedEvent, setSelectedEvent] = useState<EventTypes | null>(null);

  const { register, handleSubmit, reset, control, formState: { errors, isSubmitting } } = useForm<EventTypes>({    
    defaultValues: {
      se_id: 0,
      se_sec_id: 0,
      se_name: "",
      se_details: "",
      se_status: 0,
    }
  });

  const fetchCategory = useCallback(async () => {
    try {
      const res = await fetch("/api/events/category", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.categories)) {
        setCategories(json.categories);
      }
    } catch {
      showToast("Category List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);

  const fetchEvent = useCallback(async () => {
    try {
      const res = await fetch("/api/events/list", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.eventsData)) {
        setEvents(json.eventsData);
      }
    } catch {
      showToast("Event List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);
  

  useEffect(() => {    
    fetchCategory();
    fetchEvent();
  }, [fetchCategory,fetchEvent]);

  useEffect(() => {
    if (selectedEvent) {
      reset({
        se_id: selectedEvent.se_id,
        se_sec_id: selectedEvent.se_sec_id,
        se_name: selectedEvent.se_name,
        se_details: selectedEvent.se_details,
        se_status: selectedEvent.se_status,
      });
    }
    }, [selectedEvent, reset]);

  const filteredEvents = events.filter((event) => {
    const matchesSearch = event.se_name?.toLowerCase().includes(searchEvent.toLowerCase());
    const matchesType = selectedCategory === "" || event.se_sec_id === selectedCategory;
    return matchesSearch && matchesType;
  });

  const onSubmit = async (data: EventTypes) => {
    try {
      const recaptchaToken = await getToken("events_save_form");
      const res = await fetch("/api/events/save", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({...data, recaptchaToken}),
      });
      const result = await res.json();
      if (res.ok) {
        showToast(result.message, "success");
        reset({
          se_id: 0,
          se_sec_id: 0,
          se_name: "",
          se_details: "",
          se_status: 0,
        });
        setSelectedEvent(null);
        fetchEvent();
      }
      else {
        showToast(result.error, "danger");
      }
    } catch {
      showToast("Event creation failed.", "danger");
    }
  };

  if (isLoading) return <LoadingCMS />;

  return (
    <Container fluid className="py-3">
      <Row>        
        <Col md={8}>
          <Row xs={1} md={1} className="g-3">
            <Col md={4} className="align-self-center">
              <h1 className="fs-3">Events <small className="text-body-secondary">({filteredEvents.length})</small></h1>
            </Col>
            <Col md={4}>
              <FloatingLabel label="Search by name">
                <Form.Control value={searchEvent} onChange={(e) => setEventSearch(e.target.value)} />
              </FloatingLabel>
            </Col>
            <Col md={4}>
              <FloatingLabel label="Category">
                <Form.Select value={selectedCategory} onChange={(e) => setselectedCategory(e.target.value === "" ? "" : Number(e.target.value))}>
                <option value="">All Categories</option>
                {categories.map((category) => (
                  <option key={category.sec_id} value={category.sec_id}>
                    {category.sec_name}
                  </option>
                ))}
                </Form.Select>
              </FloatingLabel>
            </Col>
            {filteredEvents.map((event, index) => (
              <Col key={index}>
                <Card className="h-100 rounded-4 overflow-hidden">                  
                  <Card.Body className="d-flex">
                    { event.se_cover && event.se_cover.up_id > 0 ? (
                      <Card.Img className="rounded-4 img-fluid me-3 w-25" src={event.se_cover.src} alt={event.se_name} width={event.se_cover.up_width} height={event.se_cover.up_height}  />
                    ) : null}
                    <div className="flex-fill">
                      <Card.Title className="d-flex align-items-start">
                          <span className="flex-fill me-3">{event.se_name}</span>
                          {event.se_status === 1 ? <Badge bg="primary">Active</Badge> : <Badge bg="secondary">Inactive</Badge>}
                      </Card.Title>
                      <Card.Text>{excerptFromHtml(event.se_details, 50)}</Card.Text>
                    </div>
                  </Card.Body>
                  <ListGroup variant="flush">
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Category <span className="ms-3">{findValue(categories,"sec_id",event.se_sec_id,"sec_name","N/A")}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Date <span className="ms-3">{unixToDateTime(event.se_date,'date')}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="p-0">
                      <UploadEvent event={event} setEvents={setEvents} />
                    </ListGroup.Item>
                  </ListGroup>
                  <Card.Footer className="d-flex align-items-center justify-content-between">                    
                    <Button variant="outline-danger" className="w-100 rounded-pill" onClick={() => setSelectedEvent(event)}>
                        Edit
                    </Button>
                  </Card.Footer>
                </Card>
              </Col>
            ))}
          </Row>
        </Col>
        <Col md={4} className="position-sticky vh-100 overflow-y-auto" style={{ top: "1rem" }}>
          <Card className="rounded-4 bg-light">
            <Card.Body>
              <h2 className="fs-3 mb-4">Create New Event</h2>
              <Form noValidate onSubmit={handleSubmit(onSubmit)}>
                <Row className="g-3">
                    <Col md={12}>
                        <FloatingLabel label="Category">
                            <Form.Select {...register("se_sec_id", { required: "Category is required" })} isInvalid={!!errors.se_sec_id} >
                            <option value="0">Select Category</option>
                              {categories.map((category) => (
                              <option key={category.sec_id} value={category.sec_id}>
                                {category.sec_name}
                              </option>
                              ))}
                            </Form.Select>
                            <Form.Control.Feedback type="invalid">{errors.se_sec_id?.message}</Form.Control.Feedback>
                        </FloatingLabel>
                    </Col>
                    <Col md={12}>
                    <FloatingLabel label="Name">
                        <Form.Control type="text" {...register("se_name", { required: "Event Name is required" })} isInvalid={!!errors.se_name} />
                        <Form.Control.Feedback type="invalid">{errors.se_name?.message}</Form.Control.Feedback>
                    </FloatingLabel>
                    </Col>
                    <Col md={12}>
                    <Controller name="se_details" control={control} rules={{ required: "Event Details is required" }}
                        render={({ field }) => (
                        <HtmlEditor value={field.value || ""} onChange={field.onChange} />
                        )}
                    />
                    <Form.Control.Feedback type="invalid">{errors.se_details?.message}</Form.Control.Feedback>                    
                    </Col>
                    <Col md={12}>
                        <Controller name="se_status" control={control} defaultValue={0} render={({ field }) => (
                            <Form.Check type="switch" id="se_status" label="Event Status" checked={field.value === 1} onChange={(e) => field.onChange(e.target.checked ? 1 : 0)} />
                        )} />
                    </Col>
                  <Col md={12}>
                    <Stack direction="horizontal" gap={3}>
                        <Button type="submit" variant="danger" className="w-100 rounded-pill" disabled={isSubmitting}>
                        {isSubmitting ? (
                            <Stack gap={2} direction="horizontal">
                            <Spinner animation="grow" size="sm" variant="danger" />
                            <Spinner animation="grow" size="sm" variant="primary" />
                            <Spinner animation="grow" size="sm" variant="success" />
                            <span>{selectedEvent ? "Updating..." : "Creating..."}</span>
                            </Stack>
                        ) : selectedEvent ? "Update Event" : "Create Event"}
                        </Button>
                        {selectedEvent && (
                        <Button variant="outline-secondary" className="w-100 rounded-pill" onClick={() => { reset({
      se_id: 0,
      se_sec_id: 0,
      se_name: "",
      se_details: "",
      se_status: 0,
    }); setSelectedEvent(null); }} >
                            Cancel Edit
                        </Button>
                        )}
                    </Stack>
                  </Col>
                </Row>
              </Form>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  );
}
