import { userRepo, type PeopleFilters } from "@/server/repositories/user.repo";
import { tripRepo } from "@/server/repositories/trip.repo";
import { participantRepo } from "@/server/repositories/participant.repo";
import { organizerRepo } from "@/server/repositories/organizer.repo";
import { profileRepo } from "@/server/repositories/profile.repo";
import { isPastTripLastDayForReview } from "@/lib/trip-dates";
import type { UpdateProfileInput } from "@/features/profile/schemas";

export const profileService = {
  async getOwnProfile(userId: string) {
    return profileRepo.findByUserId(userId);
  },

  async findPeople(filters?: PeopleFilters) {
    return userRepo.findPeople(filters);
  },

  async updateProfile(userId: string, input: UpdateProfileInput) {
    return profileRepo.upsertByUserId(userId, {
      bio: input.bio,
      city: input.city,
      instagram: input.instagram,
      interests: input.interests,
      vibe: input.vibe,
    });
  },

  /**
   * Halaman profil publik /u/[id]. Membaca user + UserProfile + counts trip.
   * Tidak ekspos email/KYC.
   */
  async getPublicProfile(userId: string) {
    const user = await userRepo.findSocialProfileById(userId);
    if (!user) return null;

    const [organizedTrips, participations] = await Promise.all([
      tripRepo.findByOrganizerId(userId),
      participantRepo.findWithTripForProfile(userId),
    ]);

    const joinedTrips = participations
      .filter((p) => p.status !== "CANCELLED")
      .map((p) => p.trip)
      .sort(
        (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()
      );

    return {
      user,
      isVerifiedOrganizer:
        user.organizerVerification?.status === "APPROVED",
      organizedTrips,
      joinedTrips,
    };
  },

  async getProfileDashboard(userId: string) {
    const user = await userRepo.findPublicProfileById(userId);
    if (!user) {
      throw new Error("Pengguna tidak ditemukan");
    }

    const [organizedTrips, participations, verification] = await Promise.all([
      tripRepo.findByOrganizerId(userId),
      participantRepo.findWithTripForProfile(userId),
      organizerRepo.findByUserId(userId),
    ]);
    const isVerifiedOrganizer = verification?.status === "APPROVED";

    const activeJoined = participations
      .filter((p) => p.status !== "CANCELLED")
      .sort(
        (a, b) =>
          new Date(b.trip.date).getTime() - new Date(a.trip.date).getTime()
      );
    const cancelledJoined = participations
      .filter((p) => p.status === "CANCELLED")
      .sort(
        (a, b) =>
          new Date(b.trip.date).getTime() - new Date(a.trip.date).getTime()
      );

    const reviewable = activeJoined
      .filter((p) => {
        if (p.status !== "CONFIRMED") return false;
        const t = p.trip;
        if (t.organizerId === userId) return false;
        return isPastTripLastDayForReview(t.date, t.endDate);
      })
      .sort(
        (a, b) =>
          new Date(b.trip.date).getTime() - new Date(a.trip.date).getTime()
      );

    return {
      user,
      isVerifiedOrganizer,
      organizedTrips,
      activeJoined,
      cancelledJoined,
      reviewable,
    };
  },
};
