import { prisma } from "@/lib/prisma";
import {
  COMPLETION_RATE_MIN_SAMPLE,
  TRIP_LEADER_MIN_TRIPS,
} from "@/lib/trust";

export type RatingBreakdown = Record<1 | 2 | 3 | 4 | 5, number>;

export type OrganizerTrust = {
  isVerified: boolean;
  tripsCreated: number;
  /// Trip yang sudah lewat tanggal selesai-nya AND tidak dibatalkan (status != CLOSED).
  /// Dihitung on-the-fly dari endDate (fallback ke date kalau endDate null) — tidak
  /// bergantung pada Trip.status = COMPLETED yang saat ini belum pernah di-set.
  tripsCompleted: number;
  /// Trip dengan status = CLOSED (dibatalkan organizer).
  tripsCancelled: number;
  /// Akumulasi peserta CONFIRMED di seluruh trip yang sudah selesai.
  totalParticipantsServed: number;
  /// tripsCompleted / (tripsCompleted + tripsCancelled). Null kalau sample
  /// < COMPLETION_RATE_MIN_SAMPLE — mencegah angka menyesatkan untuk
  /// organizer yang masih sedikit history-nya.
  completionRate: number | null;
  avgRating: number | null;
  reviewCount: number;
  ratingBreakdown: RatingBreakdown;
  isTripLeader: boolean;
};

export const trustService = {
  async getOrganizerTrust(organizerId: string): Promise<OrganizerTrust> {
    const now = new Date();

    // Filter "trip yang sudah lewat": endDate < now, atau (endDate null AND date < now).
    // Trip multi-hari pakai endDate; trip 1 hari biasanya endDate null jadi fallback ke date.
    const pastTripFilter = {
      OR: [
        { endDate: { lt: now } },
        { AND: [{ endDate: null }, { date: { lt: now } }] },
      ],
    };

    const [
      tripsCreated,
      tripsCompleted,
      tripsCancelled,
      totalParticipantsServed,
      reviewAgg,
      ratingGroups,
      organizerVerification,
    ] = await Promise.all([
      prisma.trip.count({ where: { organizerId } }),
      prisma.trip.count({
        where: {
          organizerId,
          status: { not: "CLOSED" },
          ...pastTripFilter,
        },
      }),
      prisma.trip.count({
        where: { organizerId, status: "CLOSED" },
      }),
      prisma.tripParticipant.count({
        where: {
          status: "CONFIRMED",
          trip: {
            organizerId,
            status: { not: "CLOSED" },
            ...pastTripFilter,
          },
        },
      }),
      prisma.tripReview.aggregate({
        where: { trip: { organizerId } },
        _avg: { rating: true },
        _count: { _all: true },
      }),
      prisma.tripReview.groupBy({
        by: ["rating"],
        where: { trip: { organizerId } },
        _count: { _all: true },
      }),
      prisma.organizerVerification.findUnique({
        where: { userId: organizerId },
        select: { status: true },
      }),
    ]);

    const ratingBreakdown: RatingBreakdown = {
      1: 0,
      2: 0,
      3: 0,
      4: 0,
      5: 0,
    };
    for (const row of ratingGroups) {
      const r = row.rating;
      if (r >= 1 && r <= 5) {
        ratingBreakdown[r as 1 | 2 | 3 | 4 | 5] = row._count._all;
      }
    }

    const completionSample = tripsCompleted + tripsCancelled;
    const completionRate =
      completionSample >= COMPLETION_RATE_MIN_SAMPLE
        ? tripsCompleted / completionSample
        : null;

    const avg = reviewAgg._avg.rating;

    return {
      isVerified: organizerVerification?.status === "APPROVED",
      tripsCreated,
      tripsCompleted,
      tripsCancelled,
      totalParticipantsServed,
      completionRate,
      avgRating:
        avg != null ? Math.round(Number(avg) * 10) / 10 : null,
      reviewCount: reviewAgg._count._all,
      ratingBreakdown,
      isTripLeader: tripsCreated >= TRIP_LEADER_MIN_TRIPS,
    };
  },
};
