
import { Trip, UserRole, TripStep, Comment, Document, StepLink, StepType, StepValidationStatus } from "@/types";
import type { Tables } from "@/integrations/supabase/types";
import { format, parseISO } from "date-fns";
import { fr } from "date-fns/locale";
import type { Json } from "@/integrations/supabase/types";
import { normalizeDocumentCategory } from "@/services/documentCategories";

// Fonction pour mapper les données de la base de données vers le format frontend
type CommentRow = Tables<"comments">;
type ValidationRow = Tables<"step_validations">;
type MemberRow = Pick<Tables<"trip_members">, "user_id" | "status" | "source" | "joined_at"> & {
  profiles?: Pick<Tables<"profiles">, "id" | "name" | "email" | "role"> | null;
};
type StepRow = Tables<"trip_steps"> & {
  comments?: CommentRow[] | null;
  step_validations?: ValidationRow[] | null;
};
type DocumentRow = Tables<"documents">;
export type TripRowWithRelations = Tables<"trips"> & {
  trip_steps?: StepRow[] | null;
  documents?: DocumentRow[] | null;
  banner_url?: string | null;
  invitations?: Array<{ email: string; status: string; created_at: string; accepted_at?: string | null; accepted_by?: string | null }> | null;
  trip_members?: MemberRow[] | null;
};

export function normalizeStepLinks(value: Json | null): StepLink[] {
  if (!Array.isArray(value)) return [];
  return value.filter((item): item is { url: string; title: string } =>
    typeof item === "object" && item !== null && !Array.isArray(item) &&
    typeof item.url === "string" && typeof item.title === "string"
  );
}

export const transformTripFromDB = (dbTrip: TripRowWithRelations, userRole: UserRole): Trip => {
  const latestInvitation = dbTrip.invitations?.slice().sort((a, b) => b.created_at.localeCompare(a.created_at))[0];
  // Transform trip steps from snake_case to camelCase
  const steps = dbTrip.trip_steps ? dbTrip.trip_steps.map((step): TripStep | null => {
    // Sort comments by creation date
    const comments = step.comments ?
      [...step.comments].sort((a, b) =>
        a.created_at.localeCompare(b.created_at) || a.id.localeCompare(b.id)
      ) : [];

    // Si l'utilisateur est un voyageur, ne renvoyer que les étapes publiées
    if (userRole === 'traveler' && step.is_published === false) {
      return null; // Cette étape sera filtrée
    }

    return {
      id: step.id,
      tripId: step.trip_id,
      day: step.day,
      time: step.time,
      location: step.location,
      activity: step.activity,
      price: step.price,
      distance: step.distance,
      links: normalizeStepLinks(step.links),
      link: step.link,
      imagePath: step.image_path,
      updatedAt: step.updated_at,
      validationStatus: (userRole === "traveler"
        ? step.step_validations?.[0]?.status || "pending"
        : step.validation_status) as StepValidationStatus,
      validations: (step.step_validations || []).map((validation) => ({
        travelerId: validation.traveler_id,
        status: validation.status as StepValidationStatus,
        updatedAt: validation.updated_at,
      })),
      isPublished: step.is_published,
      comments: comments.map((comment): Comment => ({
        id: comment.id,
        userId: comment.user_id,
        userName: comment.user_name,
        content: comment.content,
        createdAt: comment.created_at
      })),
      stepType: step.step_type as StepType | undefined,
      startTime: step.start_time,
      endTime: step.end_time,
      description: step.description,
      transportType: step.transport_type,
      referenceNumber: step.reference_number,
      departureName: step.departure_name,
      arrivalName: step.arrival_name,
      estimatedDuration: step.estimated_duration,
      restaurantName: step.restaurant_name,
      cuisineType: step.cuisine_type,
      budget: step.budget,
      accommodationName: step.accommodation_name,
      roomType: step.room_type,
      checkInTime: step.check_in_time,
      checkOutTime: step.check_out_time,
      reservationNumber: step.reservation_number,
      activityType: step.activity_type,
      guideName: step.guide_name,
      walkingLevel: step.walking_level,
      breakPurpose: step.break_purpose,
      internalNotes: userRole === "planner" ? step.internal_notes : undefined
    };
  }).filter((step): step is TripStep => step !== null) : []; // Filtrer les étapes null (celles non publiées pour les voyageurs)

  // Transform documents from snake_case to camelCase
  const documents = dbTrip.documents ? dbTrip.documents.map((doc): Document => ({
    id: doc.id,
    name: doc.name,
    type: normalizeDocumentCategory(doc.type),
    url: doc.url,
    uploadedAt: doc.uploaded_at,
    stepId: doc.step_id ?? undefined,
    mimeType: doc.mime_type ?? undefined,
    sizeBytes: doc.size_bytes ?? undefined,
    uploadedBy: doc.uploaded_by ?? undefined,
  })) : [];

  // Steps should be sorted by day first, then by time
  steps.sort((a, b) => {
    if (a.day !== b.day) return a.day - b.day;
    // Compare by startTime if available, otherwise fallback to time
    const aTime = a.startTime || a.time;
    const bTime = b.startTime || b.time;
    return aTime.localeCompare(bTime);
  });

  return {
    id: dbTrip.id,
    title: dbTrip.title,
    destination: dbTrip.destination,
    startDate: dbTrip.start_date,
    endDate: dbTrip.end_date,
    plannerId: dbTrip.planner_id,
    travelerId: dbTrip.traveler_id || "",
    travelerEmail: dbTrip.traveler_email || "",
    travelerName: dbTrip.traveler_name,
    members: (dbTrip.trip_members || []).flatMap((member) => member.profiles ? [{
      userId: member.user_id,
      name: member.profiles.name,
      email: member.profiles.email,
      status: "active" as const,
      source: member.source as "legacy" | "assignment" | "invitation",
      joinedAt: member.joined_at,
    }] : []),
    invitations: (dbTrip.invitations || []).map((invitation) => ({
      email: invitation.email,
      status: invitation.status as "pending" | "accepted" | "expired" | "revoked",
      createdAt: invitation.created_at,
      acceptedAt: invitation.accepted_at ?? undefined,
      acceptedBy: invitation.accepted_by ?? undefined,
    })),
    invitationStatus: latestInvitation?.status as Trip["invitationStatus"] || null,
    coverUrl: dbTrip.cover_url,
    bannerUrl: dbTrip.banner_url,
    steps: steps,
    documents: documents
  };
};

// Fonction pour formater les dates dans le format jj/mm/aaaa
export function formatDate(dateString: string): string {
  try {
    // Utiliser date-fns pour formater la date
    return format(parseISO(dateString), 'dd/MM/yyyy', { locale: fr });
  } catch (error) {
    console.error("Erreur lors du formatage de la date:", error);
    return dateString; // Retourner la chaîne originale en cas d'erreur
  }
}

// Fonction pour transformer les données de voyage pour l'interface utilisateur
export const mapTripsData = (tripsData: Trip[]): Trip[] => {
  if (!tripsData || !Array.isArray(tripsData)) return [];
  console.log("Données mappées:", tripsData);
  return tripsData.map(trip => ({
    id: trip.id,
    title: trip.title,
    destination: trip.destination,
    startDate: trip.startDate,
    endDate: trip.endDate,
    plannerId: trip.plannerId,
    travelerId: trip.travelerId || "",
    travelerEmail: trip.travelerEmail || "",
    travelerName: trip.travelerName || "",
    coverUrl: trip.coverUrl,
    bannerUrl: trip.bannerUrl,
    steps: trip.steps || [],
    documents: trip.documents || []
  }));
};
