import { z } from 'zod'
import { TRPCError } from '@trpc/server'
import { router, adminProcedure, protectedProcedure, juryProcedure } from '../trpc'
import {
  previewRoundAssignment,
  executeRoundAssignment,
  getRoundCoverageReport,
  getUnassignedQueue,
} from '../services/round-assignment'

export const roundAssignmentRouter = router({
  /**
   * Preview round assignments without committing
   */
  preview: adminProcedure
    .input(
      z.object({
        roundId: z.string(),
        honorIntents: z.boolean().default(true),
        requiredReviews: z.number().int().min(1).max(20).default(3),
      })
    )
    .query(async ({ ctx, input }) => {
      return previewRoundAssignment(
        input.roundId,
        {
          honorIntents: input.honorIntents,
          requiredReviews: input.requiredReviews,
        },
        ctx.prisma,
      )
    }),

  /**
   * Execute round assignments (create Assignment records)
   */
  execute: adminProcedure
    .input(
      z.object({
        roundId: z.string(),
        assignments: z.array(
          z.object({
            userId: z.string(),
            projectId: z.string(),
          })
        ).min(1),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const result = await executeRoundAssignment(
        input.roundId,
        input.assignments,
        ctx.user.id,
        ctx.prisma,
      )

      if (result.errors.length > 0 && result.created === 0) {
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: result.errors.join('; '),
        })
      }

      return result
    }),

  /**
   * Get coverage report for a round
   */
  coverageReport: protectedProcedure
    .input(
      z.object({
        roundId: z.string(),
        requiredReviews: z.number().int().min(1).max(20).default(3),
      })
    )
    .query(async ({ ctx, input }) => {
      return getRoundCoverageReport(input.roundId, input.requiredReviews, ctx.prisma)
    }),

  /**
   * Get projects below required reviews threshold
   */
  unassignedQueue: protectedProcedure
    .input(
      z.object({
        roundId: z.string(),
        requiredReviews: z.number().int().min(1).max(20).default(3),
      })
    )
    .query(async ({ ctx, input }) => {
      return getUnassignedQueue(input.roundId, input.requiredReviews, ctx.prisma)
    }),

  /**
   * Get assignments for the current jury member in a specific round
   */
  getMyAssignments: juryProcedure
    .input(z.object({ roundId: z.string() }))
    .query(async ({ ctx, input }) => {
      return ctx.prisma.assignment.findMany({
        where: {
          roundId: input.roundId,
          userId: ctx.user.id,
        },
        include: {
          project: {
            select: { id: true, title: true, competitionCategory: true },
          },
          evaluation: {
            select: { id: true, status: true, globalScore: true },
          },
        },
        orderBy: { createdAt: 'asc' },
      })
    }),
})
