import { EventDetailsModal } from "@ui/components/EventDetailsModal";
import { LoadingSpinner } from "@ui/components/LoadingSpinner";
import { getTextColorFromTabloColor } 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 { useNavigate, useParams } from "react-router-dom";
import { twMerge } from "tailwind-merge";
import { useEventsByTablo } from "../hooks/events";
import { useGetAllTabloAccess, useTablosList } from "../hooks/tablos";

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

interface BookingStatusOption {
  id: BookingStatus;
  name: string;
}

const statusOptions: BookingStatusOption[] = [
  { id: "upcoming", name: "À venir" },
  { id: "past", name: "Passés" },
];

export const BookingsPage = () => {
  const { tablo_id } = useParams();
  const navigate = useNavigate();
  const [selectedTabloId, setSelectedTabloId] = useState<string>(tablo_id || "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 tablos and events
  const { data: tablos, isLoading: tablosLoading } = useTablosList();
  const { data: events = [], isLoading: eventsLoading } = useEventsByTablo(
    selectedTabloId !== "all" ? selectedTabloId : null
  );
  // Fetch all tablo accesses for permissions
  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);
      const tomorrow = new Date(today);
      tomorrow.setDate(tomorrow.getDate() + 1);

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

  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) {
        // Remove seconds from time (HH:MM:SS -> HH:MM)
        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 = () => {
    const today = new Date();
    const dateParam = today.toISOString();
    const tabloParam = selectedTabloId !== "all" ? `&tablo_id=${selectedTabloId}` : "";
    navigate(`/planning/create?date=${dateParam}${tabloParam}`);
  };

  // Check if an event can be edited (admin access required)
  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 className="flex items-center justify-between">
            <div>
              <TypographyH3>Réservations</TypographyH3>
              <TypographyMuted>Gérez vos événements et réservations</TypographyMuted>
            </div>
            <div className="flex items-center space-x-3">
              <Button onClick={handleCreateEvent}>
                <CalendarIcon className="w-4 h-4 mr-2" />
                Nouvel événement
              </Button>
            </div>
          </div>
        </div>
      </header>

      {/* Main Content */}
      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
        {/* Filters */}
        <div className="bg-card rounded-lg shadow-sm border border-border p-6 mb-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="Rechercher un événement..."
                  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 tableaux" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">Tous les tableaux</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"
                >
                  {option.name}
                </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-screen">
              <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">Aucun événement trouvé</h3>
              <p className="mt-1 text-sm text-muted-foreground">
                {searchTerm || statusFilter !== "all"
                  ? "Essayez de modifier vos filtres de recherche."
                  : "Commencez par créer votre premier événement."}
              </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)}>
                        Détails
                      </Button>
                    </div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Pagination Controls */}
        {totalItems > 0 && (
          <div className="bg-card rounded-lg shadow-sm border border-border mt-4 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>
                  Affichage de {startIndex + 1} à {Math.min(endIndex, totalItems)} sur {totalItems}{" "}
                  événements
                </span>
                <div className="flex items-center space-x-2">
                  <span className="whitespace-nowrap">Éléments par page:</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" />
                    Précédent
                  </Button>

                  <div className="flex items-center space-x-1">
                    {Array.from({ length: totalPages }, (_, i) => i + 1)
                      .filter((page) => {
                        // Show first page, last page, current page, and pages around current
                        return (
                          page === 1 || page === totalPages || Math.abs(page - currentPage) <= 1
                        );
                      })
                      .map((page, index, array) => {
                        // Add ellipsis if there's a gap
                        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}
                  >
                    Suivant
                    <ChevronRight className="w-4 h-4" />
                  </Button>
                </div>
              )}
            </div>
          </div>
        )}

        {/* Stats Summary */}
        {filteredEvents.length > 0 && (
          <div className="mt-6 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">Événements trouvés</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">À venir</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">Aujourd&apos;hui</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>
    </div>
  );
};
