import prisma from './prisma';

export type ReviewEligibility =
  | {
      eligible: true;
      source: 'job' | 'hire';
      jobId?: string;
      hireInvitationId?: string;
      workerId: string;
      workerName: string;
    }
  | { eligible: false; reason: string };

export async function checkReviewEligibility(
  jobId: string,
  customerId: string
): Promise<ReviewEligibility> {
  const job = await prisma.job.findFirst({
    where: { id: jobId, deletedAt: null },
    include: {
      worker: {
        include: { user: { select: { firstName: true, lastName: true } } },
      },
      reviews: { take: 1 },
      quotations: { where: { status: 'ACCEPTED' } },
    },
  });

  if (!job) return { eligible: false, reason: 'Job not found' };
  if (job.customerId !== customerId) {
    return { eligible: false, reason: 'You can only review workers on your own jobs' };
  }
  if (job.status !== 'COMPLETED') {
    return { eligible: false, reason: 'You can review after the job is marked completed' };
  }
  if (!job.workerId || !job.worker) {
    return { eligible: false, reason: 'No worker was hired for this job' };
  }
  if (job.reviews.length > 0) {
    return { eligible: false, reason: 'You already submitted a review for this job' };
  }

  const hiredViaQuote = job.quotations.some((q) => q.workerId === job.workerId);
  if (!hiredViaQuote) {
    return {
      eligible: false,
      reason: 'You can only review a worker you hired through an accepted quotation',
    };
  }

  return {
    eligible: true,
    source: 'job',
    jobId: job.id,
    workerId: job.workerId,
    workerName: `${job.worker.user.firstName} ${job.worker.user.lastName}`,
  };
}

/**
 * Only customers who hired the worker (accepted or completed hire invitation)
 * can leave a review for that hire.
 */
export async function checkHireReviewEligibility(
  hireInvitationId: string,
  customerId: string
): Promise<ReviewEligibility> {
  const invitation = await prisma.hireInvitation.findUnique({
    where: { id: hireInvitationId },
    include: {
      worker: {
        include: { user: { select: { firstName: true, lastName: true } } },
      },
      review: { select: { id: true } },
    },
  });

  if (!invitation) return { eligible: false, reason: 'Hire invitation not found' };
  if (invitation.customerId !== customerId) {
    return { eligible: false, reason: 'You can only review workers you hired' };
  }
  if (invitation.status !== 'ACCEPTED' && invitation.status !== 'COMPLETED') {
    return {
      eligible: false,
      reason: 'You can only review after the worker accepts your hire invitation',
    };
  }
  if (invitation.review) {
    return { eligible: false, reason: 'You already submitted a review for this hire' };
  }

  return {
    eligible: true,
    source: 'hire',
    hireInvitationId: invitation.id,
    workerId: invitation.workerId,
    workerName: `${invitation.worker.user.firstName} ${invitation.worker.user.lastName}`,
  };
}

export async function findPendingReviewJobs(customerId: string) {
  const jobs = await prisma.job.findMany({
    where: {
      customerId,
      status: 'COMPLETED',
      deletedAt: null,
      workerId: { not: null },
      reviews: { none: {} },
      quotations: { some: { status: 'ACCEPTED' } },
    },
    orderBy: { updatedAt: 'desc' },
    include: {
      category: { select: { name: true } },
      worker: {
        include: { user: { select: { firstName: true, lastName: true, avatarUrl: true } } },
      },
      quotations: { where: { status: 'ACCEPTED' } },
    },
  });

  return jobs.filter((job) =>
    job.quotations.some((q) => q.status === 'ACCEPTED' && q.workerId === job.workerId)
  );
}

export async function findPendingHireReviews(customerId: string) {
  return prisma.hireInvitation.findMany({
    where: {
      customerId,
      status: { in: ['ACCEPTED', 'COMPLETED'] },
      review: null,
    },
    orderBy: { updatedAt: 'desc' },
    include: {
      worker: {
        include: {
          user: { select: { firstName: true, lastName: true, avatarUrl: true } },
          skills: {
            take: 1,
            include: { category: { select: { name: true } } },
          },
        },
      },
    },
  });
}
