import { EventDetailsModal } from "@ui/components/EventDetailsModal";
import { LoadingSpinner } from "@ui/components/LoadingSpinner";
import { getTextColorFromTabloColor, toast } from "@xtablo/shared";
import { EventAndTablo } from "@xtablo/shared/types/events.types";
import { Button } from "@xtablo/ui/components/button";
import { ButtonGroup } from "@xtablo/ui/components/button-group";
import { Input } from "@xtablo/ui/components/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@xtablo/ui/components/select";
import { Strong, Text, TypographyH3, TypographyMuted } from "@xtablo/ui/components/typography";
import { Calendar as CalendarIcon, ChevronLeft, ChevronRight, SearchIcon } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Outlet, useNavigate } from "react-router-dom";
import { twMerge } from "tailwind-merge";
import { useEventsByTablo } from "../hooks/events";
import { useGetAllTabloAccess, useTablosList } from "../hooks/tablos";
import { useIsReadOnlyUser } from "../providers/UserStoreProvider";

type BookingStatus = "all" | "upcoming" | "past";

interface BookingStatusOption {
  id: BookingStatus;
  name: string;
}
export function EventsPage() {
  const navigate = useNavigate();
  const { t } = useTranslation(["pages", "common"]);
  const isReadOnly = useIsReadOnlyUser();

  const statusOptions: BookingStatusOption[] = [
    { id: "upcoming", name: t("pages:events.filters.upcoming") },
    { id: "past", name: t("pages:events.filters.past") },
  ];

  // Events/Bookings state
  const [selectedTabloId, setSelectedTabloId] = useState<string>("all");
  const [searchTerm, setSearchTerm] = useState("");
  const [statusFilter, setStatusFilter] = useState<BookingStatus>("upcoming");
  const [selectedEvent, setSelectedEvent] = useState<EventAndTablo | null>(null);
  const [isDetailsModalOpen, setIsDetailsModalOpen] = useState(false);
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);

  // Fetch data
  const { data: tablos, isLoading: tablosLoading } = useTablosList();
  const { data: events = [], isLoading: eventsLoading } = useEventsByTablo(
    selectedTabloId !== "all" ? selectedTabloId : null
  );
  const { data: tabloAccess } = useGetAllTabloAccess();

  // Filter and search events
  const filteredEvents = useMemo(() => {
    if (!events) return [];

    let filtered = events;

    // Search filter
    if (searchTerm) {
      filtered = filtered.filter(
        (event) =>
          event.title?.toLowerCase().includes(searchTerm.toLowerCase()) ||
          event.description?.toLowerCase().includes(searchTerm.toLowerCase()) ||
          event.tablo_name?.toLowerCase().includes(searchTerm.toLowerCase())
      );
    }

    // Status filter
    if (statusFilter !== "all") {
      const today = new Date();
      today.setHours(0, 0, 0, 0);

      filtered = filtered.filter((event) => {
        if (!event.start_date) return false;

        const eventDate = new Date(event.start_date);
        eventDate.setHours(0, 0, 0, 0);

        switch (statusFilter) {
          case "upcoming":
            return eventDate >= today;
          case "past":
            return eventDate < today;
          default:
            return true;
        }
      });
    }

    return filtered.sort((a, b) => {
      if (!a.start_date || !b.start_date) return 0;
      return new Date(a.start_date).getTime() - new Date(b.start_date).getTime();
    });
  }, [events, searchTerm, statusFilter]);

  // Pagination logic
  const totalItems = filteredEvents.length;
  const totalPages = Math.ceil(totalItems / itemsPerPage);
  const startIndex = (currentPage - 1) * itemsPerPage;
  const endIndex = startIndex + itemsPerPage;
  const paginatedEvents = filteredEvents.slice(startIndex, endIndex);

  // Reset to first page when filters or page size change
  useEffect(() => {
    setCurrentPage(1);
  }, [searchTerm, statusFilter, selectedTabloId, itemsPerPage]);

  // Events handlers
  const formatEventDateTime = (event: EventAndTablo) => {
    if (!event.start_date) return "Date non définie";

    try {
      const date = new Date(event.start_date);
      const options: Intl.DateTimeFormatOptions = {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
      };
      let formatted = date.toLocaleDateString("fr-FR", options);

      if (event.start_time) {
        const startTime = event.start_time.substring(0, 5);
        formatted += ` à ${startTime}`;
        if (event.end_time) {
          const endTime = event.end_time.substring(0, 5);
          formatted += ` - ${endTime}`;
        }
      }

      return formatted;
    } catch {
      return "Date invalide";
    }
  };

  const getEventStatusBadge = (event: EventAndTablo) => {
    if (!event.start_date) return null;

    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const eventDate = new Date(event.start_date);
    eventDate.setHours(0, 0, 0, 0);

    if (eventDate.getTime() === today.getTime()) {
      return (
        <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary/10 text-primary">
          Aujourd&apos;hui
        </span>
      );
    } else if (eventDate > today) {
      return (
        <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-secondary text-secondary-foreground">
          À venir
        </span>
      );
    } else {
      return (
        <span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-muted text-muted-foreground">
          Passé
        </span>
      );
    }
  };

  const handleCreateEvent = () => {
    if (isReadOnly) {
      toast.add(
        {
          title: t("common:error"),
          description: "Vous êtes en mode lecture seule. Vous ne pouvez pas créer d'événement.",
          type: "error",
        },
        { timeout: 5000 }
      );
      return;
    }
    const today = new Date();
    const dateParam = today.toISOString();
    const tabloParam = selectedTabloId !== "all" ? `&tablo_id=${selectedTabloId}` : "";
    navigate(`/events/create?date=${dateParam}${tabloParam}`);
  };

  const canEditEvent = (event: EventAndTablo) => {
    return tabloAccess?.find((access) => access.tablo_id === event.tablo_id && access.is_admin)
      ? true
      : false;
  };

  const handleEditEvent = (event: EventAndTablo) => {
    if (event.event_id && event.tablo_id && canEditEvent(event)) {
      navigate(`/planning/${event.tablo_id}/events/${event.event_id}/edit`);
    }
  };

  const handleViewEvent = (event: EventAndTablo) => {
    setSelectedEvent(event);
    setIsDetailsModalOpen(true);
  };

  return (
    <div className="min-h-screen">
      {/* Header */}
      <header className="bg-card shadow-sm border-b border-border">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
          <div>
            <TypographyH3>{t("pages:events.title")}</TypographyH3>
            <TypographyMuted>{t("pages:events.subtitle")}</TypographyMuted>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
        <div className="flex items-center justify-end mb-6">
          <Button onClick={handleCreateEvent} disabled={isReadOnly}>
            <CalendarIcon className="w-4 h-4 mr-2" />
            {t("pages:events.createEvent")}
          </Button>
        </div>

        <div className="space-y-6">
          {/* Filters */}
          <div className="bg-card rounded-lg shadow-sm border border-border p-6">
            <div className="flex flex-col lg:flex-row gap-4 items-start lg:items-center">
              {/* Search */}
              <div className="flex-1 w-full">
                <div className="relative">
                  <SearchIcon className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground w-4 h-4" />
                  <Input
                    type="text"
                    placeholder={t("pages:events.search")}
                    value={searchTerm}
                    onChange={(e) => setSearchTerm(e.target.value)}
                    className="pl-10 h-10"
                  />
                </div>
              </div>

              {/* Tablo Filter */}
              <div className="w-full lg:w-64">
                <Select
                  value={selectedTabloId}
                  onValueChange={(value) => setSelectedTabloId(value)}
                >
                  <SelectTrigger className="w-full h-10" aria-label="Filtrer par tableau">
                    <SelectValue placeholder="Tous les tablos" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">{t("pages:events.filters.allTablos")}</SelectItem>
                    {tablos?.map((tablo) => (
                      <SelectItem key={tablo.id} value={tablo.id}>
                        <div className="flex items-center gap-2">
                          <div
                            className={twMerge(
                              "w-2 h-2 rounded-full",
                              tablo.color || "bg-muted-foreground"
                            )}
                          />
                          {tablo.name}
                        </div>
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>

              {/* Status Filter */}
              <ButtonGroup orientation="horizontal">
                {statusOptions.map((option) => (
                  <Button
                    key={option.id}
                    variant={statusFilter === option.id ? "default" : "outline"}
                    size="sm"
                    onClick={() => setStatusFilter(option.id as BookingStatus)}
                    className="rounded-full"
                  >
                    {t(`pages:events.filters.${option.id}`)}
                  </Button>
                ))}
              </ButtonGroup>
            </div>
          </div>

          {/* Events List */}
          <div className="bg-card rounded-lg shadow-sm border border-border">
            {tablosLoading || eventsLoading ? (
              <div className="flex items-center justify-center h-64">
                <LoadingSpinner />
              </div>
            ) : paginatedEvents.length === 0 ? (
              <div className="p-12 text-center">
                <CalendarIcon className="mx-auto h-12 w-12 text-muted-foreground" />
                <h3 className="mt-2 text-sm font-medium text-foreground">
                  {t("pages:events.emptyState.title")}
                </h3>
                <p className="mt-1 text-sm text-muted-foreground">
                  {searchTerm || statusFilter !== "all"
                    ? t("pages:events.emptyState.noResults")
                    : t("pages:events.emptyState.noEvents")}
                </p>
              </div>
            ) : (
              <div className="divide-y divide-border">
                {paginatedEvents.map((event) => (
                  <div
                    key={event.event_id}
                    className="p-6 hover:bg-muted transition-colors cursor-pointer"
                  >
                    <div className="flex items-start justify-between">
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center space-x-3 mb-2">
                          <Strong className="text-lg text-foreground truncate">
                            {event.title || "Événement sans titre"}
                          </Strong>
                          {getEventStatusBadge(event)}
                        </div>

                        <div className="flex items-center space-x-4 text-sm text-muted-foreground mb-2">
                          <span className="flex items-center">
                            <CalendarIcon className="w-4 h-4 mr-1" />
                            {formatEventDateTime(event)}
                          </span>
                          {event.tablo_name && (
                            <span
                              className={twMerge(
                                "inline-flex items-center px-2 py-1 rounded-md text-xs font-medium",
                                event.tablo_color,
                                getTextColorFromTabloColor(event.tablo_color)
                              )}
                            >
                              {event.tablo_name}
                            </span>
                          )}
                        </div>

                        {event.description && (
                          <Text className="text-muted-foreground line-clamp-2">
                            {event.description}
                          </Text>
                        )}
                      </div>

                      <div className="flex items-center space-x-2 ml-4">
                        <Button variant="outline" size="sm" onClick={() => handleViewEvent(event)}>
                          {t("common:buttons.details")}
                        </Button>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>

          {/* Pagination Controls */}
          {totalItems > 0 && (
            <div className="bg-card rounded-lg shadow-sm border border-border px-6 py-4">
              <div className="flex items-center justify-between">
                <div className="flex items-center space-x-4 text-sm text-muted-foreground">
                  <span>
                    {t("pages:events.pagination.showing", {
                      start: startIndex + 1,
                      end: Math.min(endIndex, totalItems),
                      total: totalItems,
                    })}
                  </span>
                  <div className="flex items-center space-x-2">
                    <span className="whitespace-nowrap">
                      {t("pages:events.pagination.itemsPerPage")}
                    </span>
                    <Select
                      value={itemsPerPage.toString()}
                      onValueChange={(value) => setItemsPerPage(Number(value))}
                    >
                      <SelectTrigger
                        className="min-w-16 h-8"
                        aria-label="Nombre d'éléments par page"
                      >
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="5">5</SelectItem>
                        <SelectItem value="10">10</SelectItem>
                        <SelectItem value="20">20</SelectItem>
                        <SelectItem value="50">50</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                </div>

                {totalPages > 1 && (
                  <div className="flex items-center space-x-2">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setCurrentPage((prev) => Math.max(prev - 1, 1))}
                      disabled={currentPage === 1}
                    >
                      <ChevronLeft className="w-4 h-4" />
                      {t("pages:events.pagination.previous")}
                    </Button>

                    <div className="flex items-center space-x-1">
                      {Array.from({ length: totalPages }, (_, i) => i + 1)
                        .filter((page) => {
                          return (
                            page === 1 || page === totalPages || Math.abs(page - currentPage) <= 1
                          );
                        })
                        .map((page, index, array) => {
                          const prevPage = array[index - 1];
                          const showEllipsis = prevPage && page - prevPage > 1;

                          return (
                            <div key={page} className="flex items-center">
                              {showEllipsis && (
                                <span className="px-2 text-muted-foreground">...</span>
                              )}
                              <Button
                                variant={currentPage === page ? "default" : "outline"}
                                size="sm"
                                onClick={() => setCurrentPage(page)}
                                className={
                                  currentPage === page
                                    ? "bg-emerald-700 text-white hover:bg-emerald-600"
                                    : ""
                                }
                              >
                                {page}
                              </Button>
                            </div>
                          );
                        })}
                    </div>

                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => setCurrentPage((prev) => Math.min(prev + 1, totalPages))}
                      disabled={currentPage === totalPages}
                    >
                      {t("pages:events.pagination.next")}
                      <ChevronRight className="w-4 h-4" />
                    </Button>
                  </div>
                )}
              </div>
            </div>
          )}

          {/* Stats Summary */}
          {filteredEvents.length > 0 && (
            <div className="bg-card rounded-lg shadow-sm border border-border p-6">
              <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
                <div className="text-center">
                  <div className="text-2xl font-bold text-foreground">{filteredEvents.length}</div>
                  <div className="text-sm text-muted-foreground">
                    {t("pages:events.stats.found")}
                  </div>
                </div>
                <div className="text-center">
                  <div className="text-2xl font-bold text-foreground">
                    {
                      filteredEvents.filter((e) => {
                        if (!e.start_date) return false;
                        const eventDate = new Date(e.start_date);
                        return eventDate >= new Date();
                      }).length
                    }
                  </div>
                  <div className="text-sm text-muted-foreground">
                    {t("pages:events.stats.upcoming")}
                  </div>
                </div>
                <div className="text-center">
                  <div className="text-2xl font-bold text-primary">
                    {
                      filteredEvents.filter((e) => {
                        if (!e.start_date) return false;
                        const today = new Date();
                        today.setHours(0, 0, 0, 0);
                        const eventDate = new Date(e.start_date);
                        eventDate.setHours(0, 0, 0, 0);
                        return eventDate.getTime() === today.getTime();
                      }).length
                    }
                  </div>
                  <div className="text-sm text-muted-foreground">
                    {t("pages:events.stats.today")}
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>

        {/* Event Details Modal */}
        <EventDetailsModal
          event={selectedEvent}
          isOpen={isDetailsModalOpen}
          onClose={() => {
            setIsDetailsModalOpen(false);
            setSelectedEvent(null);
          }}
          onEdit={() => selectedEvent && handleEditEvent(selectedEvent)}
          canEdit={selectedEvent ? canEditEvent(selectedEvent) : false}
        />
      </main>

      {/* Render child routes (e.g. EventModal) */}
      <Outlet />
    </div>
  );
}
