import { AvailabilityCard } from "@ui/components/AvailabilityCard";
import { AvailabilityVisualization } from "@ui/components/AvailabilityVisualization";
import { toast } from "@xtablo/shared";
import { Button } from "@xtablo/ui/components/button";
import { Card, CardContent } from "@xtablo/ui/components/card";
import { Checkbox } from "@xtablo/ui/components/checkbox";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@xtablo/ui/components/dialog";
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyTitle,
} from "@xtablo/ui/components/empty";
import { Label } from "@xtablo/ui/components/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@xtablo/ui/components/tabs";
import { Strong, Text, TypographyH3, TypographyMuted } from "@xtablo/ui/components/typography";
import { Plus as PlusIcon, SaveIcon } from "lucide-react";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { EventTypeCard } from "../components/EventTypeCard";
import { EventTypeModal } from "../components/EventTypeModal";
import { ExceptionModal } from "../components/ExceptionModal";
import {
  DEFAULT_AVAILABILITIES,
  Exception,
  useAvailabilities,
  WeeklyAvailability,
} from "../hooks/availabilities";
import { EventTypeConfig, useEventTypes } from "../hooks/event-types";
import { useIsReadOnlyUser } from "../providers/UserStoreProvider";

const DAYS_OF_WEEK = [0, 1, 2, 3, 4, 5, 6];
const DAYS_OF_WEEK_DISPLAY = [
  "Lundi",
  "Mardi",
  "Mercredi",
  "Jeudi",
  "Vendredi",
  "Samedi",
  "Dimanche",
];

interface TimeRange {
  start: string;
  end: string;
}

export function AvailabilitiesPage() {
  const { t } = useTranslation(["availabilities", "common"]);
  const isReadOnly = useIsReadOnlyUser();
  const {
    updateAvailabilities,
    draftAvailabilities,
    setDraftAvailabilities,
    exceptions,
    deleteException,
    isModified,
  } = useAvailabilities();
  const { eventTypes: eventTypesData, addEventType, updateEventType } = useEventTypes();

  const [copyModalOpen, setCopyModalOpen] = useState(false);
  const [sourceDayData, setSourceDayData] = useState<{
    day: number;
    enabled: boolean;
    timeRanges: TimeRange[];
  } | null>(null);
  const [selectedDays, setSelectedDays] = useState<number[]>([]);
  const [exceptionModalOpen, setExceptionModalOpen] = useState(false);
  const [isEventTypeModalOpen, setIsEventTypeModalOpen] = useState(false);
  const [editingEventType, setEditingEventType] = useState<
    (EventTypeConfig & { id: string }) | null
  >(null);
  const [eventTypeFormData, setEventTypeFormData] = useState<
    Partial<EventTypeConfig> & { isActive?: boolean }
  >({
    name: "",
    description: "",
    duration: 60,
    bufferTime: 15,
    maxBookingsPerDay: 8,
    requiresApproval: false,
  });

  const handleCopyToOtherDays = (sourceDay: number, enabled: boolean, timeRanges: TimeRange[]) => {
    setSourceDayData({ day: sourceDay, enabled, timeRanges });
    setSelectedDays([]);
    setCopyModalOpen(true);
  };

  const applyCopyToSelectedDays = () => {
    if (!sourceDayData) return;

    const updatedAvailabilities = { ...draftAvailabilities };
    selectedDays.forEach((day) => {
      updatedAvailabilities[day] = {
        enabled: sourceDayData.enabled,
        timeRanges: [...sourceDayData.timeRanges],
      };
    });

    setDraftAvailabilities(updatedAvailabilities);
    setCopyModalOpen(false);
    setSourceDayData(null);
    setSelectedDays([]);

    toast.add({
      title: "Succès",
      description: `Horaires copiés vers ${selectedDays.length} jour(s)`,
      type: "success",
    });
  };

  const handleCreateEventType = () => {
    if (isReadOnly) {
      toast.add({
        title: t("common:error"),
        description: t("availabilities:callTypes.readOnly"),
        type: "error",
      });
      return;
    }

    setEditingEventType(null);
    setEventTypeFormData({
      name: "",
      description: "",
      duration: 60,
      isActive: true,
      bufferTime: 15,
      maxBookingsPerDay: 8,
      requiresApproval: false,
    });
    setIsEventTypeModalOpen(true);
  };

  const handleEditEventType = (id: string, eventType: EventTypeConfig) => {
    setEditingEventType({ id, ...eventType });
    setEventTypeFormData(eventType);
    setIsEventTypeModalOpen(true);
  };

  const handleSaveEventType = () => {
    if (!eventTypeFormData.name) {
      toast.add({
        title: t("common:error"),
        description: t("availabilities:callTypes.required"),
        type: "error",
      });
      return;
    }

    if (editingEventType) {
      updateEventType({
        id: editingEventType.id,
        eventType: eventTypeFormData as EventTypeConfig,
      });
    } else {
      addEventType({ eventType: eventTypeFormData as EventTypeConfig });
    }

    setIsEventTypeModalOpen(false);
    setEditingEventType(null);
  };

  // Filter exceptions to only show upcoming dates (today and future)
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const upcomingExceptions = exceptions
    .map((exception, originalIndex) => ({ exception, originalIndex }))
    .filter(({ exception }) => {
      const exceptionDate = new Date(exception.date);
      exceptionDate.setHours(0, 0, 0, 0);
      return exceptionDate >= today;
    });

  return (
    <div className="min-h-screen">
      <header className="bg-card shadow-sm border-b border-[#804EEC]/20">
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
          <div>
            <TypographyH3>{t("availabilities:title")}</TypographyH3>
            <TypographyMuted>{t("availabilities:subtitle")}</TypographyMuted>
          </div>
        </div>
      </header>

      <main className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
        <Tabs defaultValue="availabilities" className="w-full">
          <TabsList className="mb-6 border border-[#804EEC]/25 bg-[#804EEC]/5 p-1">
            <TabsTrigger
              value="availabilities"
              className="data-[state=active]:bg-[#804EEC] data-[state=active]:text-white"
            >
              {t("availabilities:tabs.availabilities")}
            </TabsTrigger>
            <TabsTrigger
              value="exceptions"
              className="data-[state=active]:bg-[#804EEC] data-[state=active]:text-white"
            >
              {t("availabilities:tabs.exceptions")}
            </TabsTrigger>
            <TabsTrigger
              value="visualisation"
              className="data-[state=active]:bg-[#804EEC] data-[state=active]:text-white"
            >
              {t("availabilities:tabs.visualization")}
            </TabsTrigger>
            <TabsTrigger
              value="call-types"
              className="data-[state=active]:bg-[#804EEC] data-[state=active]:text-white"
            >
              {t("availabilities:tabs.callTypes")}
            </TabsTrigger>
          </TabsList>

          <TabsContent value="availabilities" className="space-y-4">
            <div className="flex gap-2 mb-4">
              {isModified && (
                <Button
                  size="sm"
                  variant="default"
                  className="bg-[#804EEC] text-white hover:bg-[#6f3fd4]"
                  onClick={() => {
                    updateAvailabilities({
                      updatedAvailabilities: draftAvailabilities,
                      newException: null,
                    });
                  }}
                >
                  <SaveIcon /> {t("availabilities:actions.save")}
                </Button>
              )}
              <Button
                size="sm"
                onClick={() => {
                  updateAvailabilities({
                    updatedAvailabilities: DEFAULT_AVAILABILITIES,
                  });
                }}
                className="py-1 border border-[#804EEC]/35 text-[#804EEC] bg-white hover:bg-[#804EEC]/10"
              >
                {t("availabilities:actions.businessHours")}
              </Button>
              <Button
                size="sm"
                variant="outline"
                onClick={() => {
                  const newAvailabilities: WeeklyAvailability = {};
                  DAYS_OF_WEEK.forEach((day) => {
                    newAvailabilities[day] = {
                      enabled: false,
                      timeRanges: [{ start: "09:00", end: "17:00" }],
                    };
                  });
                  updateAvailabilities({
                    updatedAvailabilities: newAvailabilities,
                  });
                }}
                className="py-1 border-[#804EEC]/35 text-[#804EEC] hover:bg-[#804EEC]/10 hover:text-[#6f3fd4]"
              >
                {t("availabilities:actions.disableAll")}
              </Button>
            </div>

            <div className="flex items-start">
              <div className="flex-1 pr-6 border-r border-[#804EEC]/20">
                <div className="grid grid-cols-2 gap-4">
                  {DAYS_OF_WEEK.map((day) => (
                    <AvailabilityCard
                      key={day}
                      day={day}
                      enabled={draftAvailabilities[day]?.enabled || false}
                      onEnabledChange={(enabled) => {
                        setDraftAvailabilities({
                          ...draftAvailabilities,
                          [day]: {
                            ...draftAvailabilities[day],
                            enabled,
                          },
                        });
                      }}
                      timeRanges={draftAvailabilities[day]?.timeRanges || []}
                      onTimeRangesChange={(ranges) => {
                        setDraftAvailabilities({
                          ...draftAvailabilities,
                          [day]: {
                            ...draftAvailabilities[day],
                            timeRanges: ranges,
                          },
                        });
                      }}
                      onCopyToOtherDays={handleCopyToOtherDays}
                    />
                  ))}
                </div>
              </div>

              <div className="w-80 pl-6">
                <div className="space-y-6">
                  <div>
                    <h3 className="text-xl font-semibold mb-2">
                      {t("availabilities:timezone.title")}
                    </h3>
                    <Text className="text-gray-500">
                      {t("availabilities:timezone.description")}
                    </Text>
                  </div>

                  <Card className="bg-muted/30 border-[#804EEC]/20">
                    <CardContent className="px-4">
                      <Strong className="block mb-2">{t("availabilities:timezone.your")}</Strong>
                      <Text className="text-gray-500">
                        {Intl.DateTimeFormat().resolvedOptions().timeZone}
                      </Text>
                      <Text className="text-sm text-gray-400 mt-2">
                        {new Date().toLocaleTimeString([], {
                          hour: "2-digit",
                          minute: "2-digit",
                        })}{" "}
                        - {t("availabilities:timezone.localTime")}
                      </Text>
                    </CardContent>
                  </Card>

                  <Card className="bg-muted/30 border-[#804EEC]/20">
                    <CardContent className="px-4">
                      <Strong className="block mb-2">Information</Strong>
                      <Text className="text-gray-500 text-sm">
                        {t("availabilities:timezone.info")}
                      </Text>
                    </CardContent>
                  </Card>
                </div>
              </div>
            </div>
          </TabsContent>

          <TabsContent value="visualisation">
            <AvailabilityVisualization
              draftAvailabilities={draftAvailabilities}
              slotDurationMinutes={60}
            />
          </TabsContent>

          <TabsContent value="exceptions" className="space-y-6">
            <div className="flex justify-between items-center">
              <div>
                <h3 className="text-xl font-semibold">{t("availabilities:exceptions.title")}</h3>
                <Text className="text-muted-foreground mt-1">
                  {t("availabilities:exceptions.description")}
                </Text>
              </div>
              {upcomingExceptions.length > 0 && (
                <Button
                  variant="default"
                  size="lg"
                  onClick={() => setExceptionModalOpen(true)}
                  className="bg-[#804EEC] text-white hover:bg-[#6f3fd4]"
                >
                  <PlusIcon /> {t("availabilities:actions.addException")}
                </Button>
              )}
            </div>

            {upcomingExceptions.length === 0 ? (
              <Empty>
                <EmptyHeader>
                  <EmptyTitle>{t("availabilities:exceptions.empty.title")}</EmptyTitle>
                  <EmptyDescription>
                    {t("availabilities:exceptions.empty.description")}
                  </EmptyDescription>
                </EmptyHeader>
                <EmptyContent>
                  <Button
                    variant="default"
                    size="lg"
                    onClick={() => setExceptionModalOpen(true)}
                    className="bg-[#804EEC] text-white hover:bg-[#6f3fd4]"
                  >
                    <PlusIcon /> {t("availabilities:actions.addException")}
                  </Button>
                </EmptyContent>
              </Empty>
            ) : (
              <div className="grid gap-4">
                {upcomingExceptions.map(({ exception, originalIndex }) => (
                  <div
                    key={`${exception.date}-${originalIndex}`}
                    className="bg-white dark:bg-gray-700/40 rounded-lg shadow-sm dark:shadow-gray-900/20 p-4 border border-[#804EEC]/20"
                  >
                    <div className="flex justify-between items-start">
                      <div className="flex-1">
                        <div className="flex items-center gap-3 mb-2">
                          <Strong className="text-lg">
                            {new Date(exception.date).toLocaleDateString("fr-FR", {
                              weekday: "long",
                              year: "numeric",
                              month: "long",
                              day: "numeric",
                            })}
                          </Strong>
                          <span
                            className={`px-2 py-1 rounded-full text-xs font-medium ${
                              exception.type === "day"
                                ? "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200"
                                : "bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200"
                            }`}
                          >
                            {exception.type === "day"
                              ? t("availabilities:exceptions.type.day")
                              : t("availabilities:exceptions.type.hours")}
                          </span>
                        </div>

                        {exception.type === "hours" && "hours" in exception && (
                          <div className="space-y-1">
                            <Text className="text-sm text-gray-600 dark:text-gray-400 font-medium">
                              {t("availabilities:exceptions.availableSlots")}
                            </Text>
                            <div className="flex flex-wrap gap-2">
                              {exception.hours.map((timeRange, timeIndex) => (
                                <span
                                  key={timeIndex}
                                  className="px-2 py-1 bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 rounded text-sm"
                                >
                                  {timeRange.start} - {timeRange.end}
                                </span>
                              ))}
                            </div>
                          </div>
                        )}
                      </div>

                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => {
                          deleteException(
                            { exceptionIndex: originalIndex },
                            {
                              onSuccess: () => {
                                toast.add({
                                  title: t("common:messages.success"),
                                  description: t("availabilities:success.exceptionDeleted"),
                                  type: "success",
                                });
                              },
                              onError: (err) => {
                                console.error(err);
                                toast.add({
                                  title: t("common:messages.error"),
                                  description: t("availabilities:error.exceptionFailed"),
                                  type: "error",
                                });
                              },
                            }
                          );
                        }}
                        className="text-destructive hover:text-destructive/90 border-destructive/50 hover:border-destructive"
                      >
                        {t("common:buttons.delete")}
                      </Button>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </TabsContent>

          <TabsContent value="call-types" className="space-y-6">
            <section className="rounded-2xl border border-[#804EEC]/25 bg-card p-6">
              <div className="mb-5 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <div>
                  <h3 className="text-xl font-semibold">{t("availabilities:callTypes.title")}</h3>
                  <Text className="text-muted-foreground">
                    {t("availabilities:callTypes.description")}
                  </Text>
                </div>
                <Button
                  onClick={handleCreateEventType}
                  disabled={isReadOnly}
                  className="bg-[#804EEC] hover:bg-[#6f3fd4] text-white"
                >
                  <PlusIcon className="w-4 h-4 mr-2" />
                  {t("availabilities:callTypes.create")}
                </Button>
              </div>

              {eventTypesData.length === 0 ? (
                <div className="rounded-xl border border-dashed border-[#804EEC]/35 bg-white/70 dark:bg-[#804EEC]/10 p-8 text-center">
                  <Text className="text-[#5c3aa9] dark:text-[#CDB8FF]">
                    {t("availabilities:callTypes.empty")}
                  </Text>
                </div>
              ) : (
                <div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
                  {eventTypesData.map((eventType) => (
                    <EventTypeCard
                      key={eventType.id}
                      eventType={eventType}
                      handleEditEventType={handleEditEventType}
                    />
                  ))}
                </div>
              )}
            </section>
          </TabsContent>
        </Tabs>
      </main>

      {/* Copy Dialog */}
      <Dialog open={copyModalOpen} onOpenChange={setCopyModalOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>
              {t("availabilities:copy.title", {
                day: sourceDayData ? DAYS_OF_WEEK_DISPLAY[sourceDayData.day] : "",
              })}
            </DialogTitle>
            <DialogDescription>{t("availabilities:copy.description")}</DialogDescription>
          </DialogHeader>

          <div className="space-y-3 max-h-60 overflow-y-auto">
            {DAYS_OF_WEEK.filter((day) => day !== sourceDayData?.day).map((day) => (
              <div key={day} className="flex items-center gap-2">
                <Checkbox
                  checked={selectedDays.includes(day)}
                  onCheckedChange={(checked) => {
                    if (checked) {
                      setSelectedDays([...selectedDays, day]);
                    } else {
                      setSelectedDays(selectedDays.filter((d) => d !== day));
                    }
                  }}
                  id={`day-${day}`}
                />
                <Label htmlFor={`day-${day}`}>{DAYS_OF_WEEK_DISPLAY[day]}</Label>
              </div>
            ))}
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setCopyModalOpen(false)}>
              {t("common:buttons.cancel")}
            </Button>
            <Button
              variant="default"
              disabled={selectedDays.length === 0}
              onClick={applyCopyToSelectedDays}
              className="bg-[#804EEC] text-white hover:bg-[#6f3fd4]"
            >
              {t("availabilities:copy.copyTo", { count: selectedDays.length })}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <EventTypeModal
        isModalOpen={isEventTypeModalOpen}
        setIsModalOpen={setIsEventTypeModalOpen}
        editingEventType={editingEventType}
        formData={eventTypeFormData as EventTypeConfig}
        setFormData={setEventTypeFormData}
        handleSaveEventType={handleSaveEventType}
      />

      <ExceptionModal
        isOpen={exceptionModalOpen}
        onClose={() => setExceptionModalOpen(false)}
        onSubmit={(newException: Exception) => {
          updateAvailabilities({
            updatedAvailabilities: draftAvailabilities,
            newException: newException,
          });
        }}
      />
    </div>
  );
}
