
import { Trip } from "@/types";
import { TripItinerary } from "./TripItinerary";
import { TripDocuments } from "./TripDocuments";
import { useCallback, useRef, useState, useEffect } from "react";
import { AddStepDialog } from "../AddStepDialog";
import { TripHeader } from "../TripHeader";
import { EditTripDialog } from "../EditTripDialog";
import { Button } from "@/components/ui/button";
import { ChevronUp, FilePlus2, Pencil, Trash2 } from "lucide-react";
import { DocumentUpload } from "../documents/DocumentUpload";
import { InvitationStatus } from "../InvitationStatus";
import { useTrips } from "@/contexts/TripContext";
import { useNavigate, useSearchParams } from "react-router-dom";
import { toast } from "sonner";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { PlannerStepPanel } from "@/components/dashboard/step/PlannerStepPanel";
import { getTripDays } from "@/services/itineraryGuards";
import { format, parseISO } from "date-fns";
import { fr } from "date-fns/locale";
import { clearRememberedStep, getRememberedStep, rememberSelectedStep, resolveSelectedTripStep, updateSelectedStepParam, type StepSelectionScope } from "@/services/stepSelectionUrl";
import { StepDetailDialog } from "@/components/dashboard/step/details/StepDetailDialog";
import { readPlannerUiState, updatePlannerUiState } from "@/services/plannerUiState";

interface TripContentProps {
  trip: Trip;
  isPlanner: boolean;
  error?: string;
  localError?: string;
  showWorkspaceChrome?: boolean;
  showGeneralDocuments?: boolean;
}

export function TripContent({ trip, isPlanner, error, localError, showWorkspaceChrome = true, showGeneralDocuments = true }: TripContentProps) {
  const [isAddStepDialogOpen, setIsAddStepDialogOpen] = useState(false);
  const [initialStepDay, setInitialStepDay] = useState(1);
  const initialPlannerUi = isPlanner ? readPlannerUiState(sessionStorage, trip.id) : {};
  const [isEditDialogOpen, setIsEditDialogOpen] = useState(initialPlannerUi.isEditingTrip === true);
  const [editStepId, setEditStepId] = useState<string | null>(initialPlannerUi.editStepId || null);
  const [isStepPanelDismissed, setIsStepPanelDismissed] = useState(false);
  const [isAddDocumentDialogOpen, setIsAddDocumentDialogOpen] = useState(false);
  const [showScrollButton, setShowScrollButton] = useState(false);
  const { deleteTrip } = useTrips();
  const navigate = useNavigate();
  const deletingRef = useRef(false);
  const [isDeleting, setIsDeleting] = useState(false);
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
  const [showInvitation, setShowInvitation] = useState(false);
  const [searchParams, setSearchParams] = useSearchParams();
  const selectionScope: StepSelectionScope = isPlanner ? "planner" : "traveler";
  const requestedStepId = searchParams.get("step");
  const requestedDay = Number(searchParams.get("day"));
  const selectableSteps = isPlanner ? trip.steps : trip.steps.filter((step) => step.isPublished === true);
  const rememberedStepId = getRememberedStep(sessionStorage, selectionScope, trip.id)
    || (isPlanner ? readPlannerUiState(sessionStorage, trip.id).selectedStepId || null : null);
  const selectedStep = resolveSelectedTripStep(selectableSteps, requestedStepId);
  const visibleSelectedStep = isStepPanelDismissed ? null : selectedStep;
  const tripDays = getTripDays(trip.startDate, trip.endDate);
  const selectedDay = tripDays.some(({ day }) => day === requestedDay)
    ? requestedDay
    : selectedStep?.day || tripDays[0]?.day || 1;
  const selectedDayDate = selectedStep
    ? (() => {
        const date = getTripDays(trip.startDate, trip.endDate).find(({ day }) => day === selectedStep.day)?.date;
        return date ? format(parseISO(date), "EEEE d MMMM yyyy", { locale: fr }) : null;
      })()
    : null;

  const setSelectedStep = useCallback((stepId: string | null) => {
    setIsStepPanelDismissed(!stepId);
    if (stepId) rememberSelectedStep(sessionStorage, selectionScope, trip.id, stepId);
    else clearRememberedStep(sessionStorage, selectionScope, trip.id);
    if (isPlanner) updatePlannerUiState(sessionStorage, trip.id, {
      selectedStepId: stepId || undefined,
      editStepId: stepId ? readPlannerUiState(sessionStorage, trip.id).editStepId : undefined,
    });
    const nextSearch = updateSelectedStepParam(searchParams, stepId);
    const nextStep = stepId ? selectableSteps.find((step) => step.id === stepId) : null;
    if (nextStep) nextSearch.set("day", String(nextStep.day));
    if (stepId) nextSearch.set("panel", "step");
    else nextSearch.delete("panel");
    setSearchParams(nextSearch, { replace: true });
  }, [isPlanner, searchParams, selectableSteps, selectionScope, setSearchParams, trip.id]);

  const setSelectedDay = useCallback((day: number) => {
    const next = new URLSearchParams(searchParams);
    next.set("day", String(day));
    const stepForOtherDay = selectedStep && selectedStep.day !== day;
    if (stepForOtherDay) {
      next.delete("step"); next.delete("panel");
      clearRememberedStep(sessionStorage, selectionScope, trip.id);
      if (isPlanner) updatePlannerUiState(sessionStorage, trip.id, { selectedStepId: undefined, editStepId: undefined });
    }
    setSearchParams(next);
  }, [isPlanner, searchParams, selectedStep, selectionScope, setSearchParams, trip.id]);

  const closeSelectedStep = useCallback(() => {
    setIsStepPanelDismissed(true);
    setEditStepId(null);
    clearRememberedStep(sessionStorage, selectionScope, trip.id);
    if (isPlanner) updatePlannerUiState(sessionStorage, trip.id, { selectedStepId: undefined, editStepId: undefined });
    const next = updateSelectedStepParam(new URLSearchParams(searchParams), null);
    next.delete("panel");
    setSearchParams(next, { replace: true });
  }, [isPlanner, searchParams, selectionScope, setSearchParams, trip.id]);

  useEffect(() => {
    if (requestedStepId) {
      if (resolveSelectedTripStep(selectableSteps, requestedStepId)) {
        rememberSelectedStep(sessionStorage, selectionScope, trip.id, requestedStepId);
        if (isPlanner) updatePlannerUiState(sessionStorage, trip.id, { selectedStepId: requestedStepId });
        if (searchParams.get("panel") !== "step" || requestedDay !== selectedStep?.day) {
          const next = new URLSearchParams(searchParams); next.set("panel", "step"); if (selectedStep) next.set("day", String(selectedStep.day)); setSearchParams(next, { replace: true });
        }
      } else {
        setSelectedStep(null);
      }
      return;
    }
    if (rememberedStepId) {
      clearRememberedStep(sessionStorage, selectionScope, trip.id);
      if (isPlanner) updatePlannerUiState(sessionStorage, trip.id, { selectedStepId: undefined, editStepId: undefined });
    }
  }, [isPlanner, rememberedStepId, requestedDay, requestedStepId, searchParams, selectableSteps, selectedStep, selectionScope, setSearchParams, setSelectedStep, trip.id]);

  useEffect(() => {
    if (!isPlanner || !editStepId) return;
    if (!trip.steps.some((step) => step.id === editStepId)) {
      updatePlannerUiState(sessionStorage, trip.id, { editStepId: undefined });
      setEditStepId(null);
    }
  }, [editStepId, isPlanner, trip.id, trip.steps]);

  const handleDeleteTrip = async () => {
    if (deletingRef.current) return;
    deletingRef.current = true;
    setIsDeleting(true);
    try {
      await deleteTrip(trip.id);
      toast.success("Voyage supprimé avec succès");
      setIsDeleteDialogOpen(false);
      navigate("/dashboard", { replace: true });
    } catch (deleteError) {
      console.error("Échec de la suppression du voyage", deleteError);
      toast.error("Le voyage n’a pas été supprimé. Veuillez réessayer.");
    } finally {
      deletingRef.current = false;
      setIsDeleting(false);
    }
  };

  // Add scroll event listener
  useEffect(() => {
    const handleScroll = () => {
      setShowScrollButton(window.scrollY > 300);
    };

    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  const scrollToTop = () => {
    window.scrollTo({ top: 0, behavior: 'smooth' });
  };

  const handleAddStep = (day = 1) => {
    setInitialStepDay(day);
    setIsAddStepDialogOpen(true);
  };

  const handleEditTrip = () => {
    updatePlannerUiState(sessionStorage, trip.id, { isEditingTrip: true });
    setIsEditDialogOpen(true);
  };

  const closeEditTrip = () => {
    updatePlannerUiState(sessionStorage, trip.id, { isEditingTrip: undefined });
    setIsEditDialogOpen(false);
  };

  const openEditStep = (stepId: string) => {
    updatePlannerUiState(sessionStorage, trip.id, { selectedStepId: stepId, editStepId: stepId });
    setEditStepId(stepId);
  };

  const closeEditStep = () => {
    updatePlannerUiState(sessionStorage, trip.id, { editStepId: undefined });
    setEditStepId(null);
  };

  const handleAddDocument = () => {
    setIsAddDocumentDialogOpen(true);
    console.log("Add document button clicked");
  };

  // Header content - Should span the full width
  const headerContent = (
    <div className="mb-6 w-full">
      <TripHeader
        title={trip.title}
        destination={trip.destination}
        startDate={trip.startDate}
        endDate={trip.endDate}
        bannerUrl={trip.bannerUrl}
        coverUrl={trip.coverUrl}
        isPlanner={isPlanner}
        onAddStep={handleAddStep}
        onInvite={() => setShowInvitation((visible) => !visible)}
        membersCount={trip.members?.length || 0}
      />
      {isPlanner && showInvitation && <InvitationStatus
        tripId={trip.id}
        invitations={trip.invitations || []}
        members={trip.members || []}
      />}
      {isPlanner && <div className="mt-3 flex flex-wrap justify-end gap-2"><Button size="sm" variant="ghost" onClick={handleEditTrip}><Pencil className="mr-2 h-4 w-4" />Modifier le voyage</Button><Button size="sm" variant="ghost" onClick={handleAddDocument}><FilePlus2 className="mr-2 h-4 w-4" />Document général</Button><Button size="sm" variant="ghost" className="text-destructive" disabled={isDeleting} onClick={() => setIsDeleteDialogOpen(true)}><Trash2 className="mr-2 h-4 w-4" />Supprimer</Button></div>}

      {/* Display errors if any */}
      {(error || localError) && (
        <div className="bg-red-50 border border-red-200 text-red-800 p-4 rounded-md">
          <p className="font-medium">Une erreur est survenue:</p>
          <p>{error || localError}</p>
        </div>
      )}

    </div>
  );

  // Main content
  const mainContent = (
    <div className="space-y-8">
      {/* Itinerary Section */}
      <section>
        <TripItinerary
          tripId={trip.id}
          steps={trip.steps || []}
          isPlanner={isPlanner}
          onAddStep={handleAddStep}
          startDate={trip.startDate}
          endDate={trip.endDate}
          members={trip.members}
          documents={trip.documents}
          onSelectStep={(step) => setSelectedStep(step.id)}
          selectedDay={selectedDay}
          selectedStepId={visibleSelectedStep?.id}
          onSelectDay={setSelectedDay}
        />
      </section>

      {/* Add Step Dialog */}
      <AddStepDialog
        isOpen={isAddStepDialogOpen}
        onClose={() => setIsAddStepDialogOpen(false)}
        tripId={trip.id}
        initialDay={initialStepDay}
        startDate={trip.startDate}
        endDate={trip.endDate}
      />

      {isPlanner && (
        <>
          <EditTripDialog
            trip={trip}
            isOpen={isEditDialogOpen}
            onOpenChange={(open) => open ? handleEditTrip() : closeEditTrip()}
          />
          <DocumentUpload
            tripId={trip.id}
            isOpen={isAddDocumentDialogOpen}
            onClose={() => setIsAddDocumentDialogOpen(false)}
          />
        </>
      )}
    </div>
  );

  const generalDocuments = (
    <div className="mt-8">
      <TripDocuments
        tripId={trip.id}
        documents={trip.documents || []}
        isPlanner={isPlanner}
      />
    </div>
  );

  return (
    <div className={`page-shell relative flex w-full flex-col transition-[padding] ${visibleSelectedStep ? "lg:pr-[444px]" : ""}`}>
      {showWorkspaceChrome && headerContent}{mainContent}{showGeneralDocuments && generalDocuments}
      {isPlanner && <PlannerStepPanel step={visibleSelectedStep} members={trip.members} startDate={trip.startDate} endDate={trip.endDate} onClose={closeSelectedStep} editStepId={editStepId} onEditOpen={openEditStep} onEditClose={closeEditStep} />}
      {!isPlanner && visibleSelectedStep && <StepDetailDialog step={visibleSelectedStep} isPlanner={false} isOpen onClose={closeSelectedStep} onEdit={() => undefined} onPublish={async () => undefined} pendingStatus={null} dayDate={selectedDayDate} members={trip.members} />}

      <AlertDialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Supprimer définitivement ce voyage ?</AlertDialogTitle>
            <AlertDialogDescription>
              « {trip.title} », ses étapes, commentaires et documents seront supprimés. Cette action est irréversible.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel disabled={isDeleting}>Annuler</AlertDialogCancel>
            <AlertDialogAction className="bg-destructive text-destructive-foreground hover:bg-destructive/90" disabled={isDeleting} onClick={(event) => {
              event.preventDefault();
              void handleDeleteTrip();
            }}>
              {isDeleting ? "Suppression…" : "Supprimer définitivement"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {/* Scroll to top button - with z-index 50 to ensure it's above everything */}
      {showScrollButton && (
        <Button
          className="fixed bottom-8 right-8 rounded-full p-3 shadow-lg z-50"
          onClick={scrollToTop}
          size="icon"
        >
          <ChevronUp className="h-6 w-6" />
        </Button>
      )}
    </div>
  );
}
