import { z } from 'zod'
import { router, adminProcedure } from '../trpc'
import { resolveMemberContext } from '@/server/services/competition-context'
import { evaluateAssignmentPolicy } from '@/server/services/assignment-policy'

export const assignmentPolicyRouter = router({
  /**
   * Get the fully-resolved assignment policy for a specific member in a round.
   * Returns cap, cap mode, buffer, category bias — all with provenance.
   */
  getMemberPolicy: adminProcedure
    .input(z.object({ roundId: z.string(), userId: z.string() }))
    .query(async ({ input }) => {
      const ctx = await resolveMemberContext(input.roundId, input.userId)
      return evaluateAssignmentPolicy(ctx)
    }),

  /**
   * Get policy summary for all members in a jury group for a given round.
   * Useful for admin dashboards showing cap compliance across the group.
   */
  getGroupPolicySummary: adminProcedure
    .input(z.object({ juryGroupId: z.string(), roundId: z.string() }))
    .query(async ({ ctx, input }) => {
      const members = await ctx.prisma.juryGroupMember.findMany({
        where: { juryGroupId: input.juryGroupId },
        include: {
          user: { select: { id: true, name: true, email: true } },
        },
      })

      const results = await Promise.all(
        members.map(async (member) => {
          try {
            const memberCtx = await resolveMemberContext(input.roundId, member.userId)
            const policy = evaluateAssignmentPolicy(memberCtx)
            return {
              userId: member.userId,
              userName: member.user.name,
              userEmail: member.user.email,
              role: member.role,
              policy,
            }
          } catch (err) {
            console.error('[AssignmentPolicy] Failed to resolve member context:', err)
            return null
          }
        }),
      )

      return results.filter(Boolean)
    }),

  /**
   * Get cap compliance report for a round.
   * Groups members into overCap, atCap, belowCap, and noCap buckets.
   */
  getCapComplianceReport: adminProcedure
    .input(z.object({ roundId: z.string() }))
    .query(async ({ ctx, input }) => {
      const round = await ctx.prisma.round.findUniqueOrThrow({
        where: { id: input.roundId },
        select: { juryGroupId: true },
      })

      if (!round.juryGroupId) {
        return { overCap: [], atCap: [], belowCap: [], noCap: [] }
      }

      const members = await ctx.prisma.juryGroupMember.findMany({
        where: { juryGroupId: round.juryGroupId },
        include: {
          user: { select: { id: true, name: true, email: true } },
        },
      })

      const report: {
        overCap: Array<{ userId: string; userName: string | null; overCapBy: number }>
        atCap: Array<{ userId: string; userName: string | null }>
        belowCap: Array<{ userId: string; userName: string | null; remaining: number }>
        noCap: Array<{ userId: string; userName: string | null }>
      } = { overCap: [], atCap: [], belowCap: [], noCap: [] }

      for (const member of members) {
        try {
          const memberCtx = await resolveMemberContext(input.roundId, member.userId)
          const policy = evaluateAssignmentPolicy(memberCtx)

          if (policy.effectiveCapMode.value === 'NONE') {
            report.noCap.push({ userId: member.userId, userName: member.user.name })
          } else if (policy.isOverCap) {
            report.overCap.push({
              userId: member.userId,
              userName: member.user.name,
              overCapBy: policy.overCapBy,
            })
          } else if (policy.remainingCapacity === 0) {
            report.atCap.push({ userId: member.userId, userName: member.user.name })
          } else {
            report.belowCap.push({
              userId: member.userId,
              userName: member.user.name,
              remaining: policy.remainingCapacity,
            })
          }
        } catch (err) {
          console.error('[AssignmentPolicy] Failed to evaluate policy for member:', err)
        }
      }

      return report
    }),
})
