import { z } from 'zod'
import { router, adminProcedure } from '../trpc'
import { logAudit } from '../utils/audit'

export const gracePeriodRouter = router({
  /**
   * Grant a grace period to a juror
   */
  grant: adminProcedure
    .input(
      z.object({
        roundId: z.string(),
        userId: z.string(),
        projectId: z.string().optional(),
        extendedUntil: z.date(),
        reason: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const gracePeriod = await ctx.prisma.gracePeriod.create({
        data: {
          ...input,
          grantedById: ctx.user.id,
        },
      })

      // Audit log
      await logAudit({
        prisma: ctx.prisma,
        userId: ctx.user.id,
        action: 'GRANT_GRACE_PERIOD',
        entityType: 'GracePeriod',
        entityId: gracePeriod.id,
        detailsJson: {
          roundId: input.roundId,
          userId: input.userId,
          projectId: input.projectId,
          extendedUntil: input.extendedUntil.toISOString(),
        },
        ipAddress: ctx.ip,
        userAgent: ctx.userAgent,
      })

      return gracePeriod
    }),

  /**
   * List grace periods for a round
   */
  listByRound: adminProcedure
    .input(z.object({ roundId: z.string() }))
    .query(async ({ ctx, input }) => {
      return ctx.prisma.gracePeriod.findMany({
        where: { roundId: input.roundId },
        include: {
          user: { select: { id: true, name: true, email: true } },
          grantedBy: { select: { id: true, name: true } },
        },
        orderBy: { createdAt: 'desc' },
      })
    }),

  /**
   * List active grace periods for a round
   */
  listActiveByRound: adminProcedure
    .input(z.object({ roundId: z.string() }))
    .query(async ({ ctx, input }) => {
      return ctx.prisma.gracePeriod.findMany({
        where: {
          roundId: input.roundId,
          extendedUntil: { gte: new Date() },
        },
        include: {
          user: { select: { id: true, name: true, email: true } },
          grantedBy: { select: { id: true, name: true } },
        },
        orderBy: { extendedUntil: 'asc' },
      })
    }),

  /**
   * Get grace periods for a specific user in a round
   */
  getByUser: adminProcedure
    .input(
      z.object({
        roundId: z.string(),
        userId: z.string(),
      })
    )
    .query(async ({ ctx, input }) => {
      return ctx.prisma.gracePeriod.findMany({
        where: {
          roundId: input.roundId,
          userId: input.userId,
        },
        orderBy: { createdAt: 'desc' },
      })
    }),

  /**
   * Update a grace period
   */
  update: adminProcedure
    .input(
      z.object({
        id: z.string(),
        extendedUntil: z.date().optional(),
        reason: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const { id, ...data } = input

      const gracePeriod = await ctx.prisma.gracePeriod.update({
        where: { id },
        data,
      })

      // Audit log
      await logAudit({
        prisma: ctx.prisma,
        userId: ctx.user.id,
        action: 'UPDATE_GRACE_PERIOD',
        entityType: 'GracePeriod',
        entityId: id,
        detailsJson: data,
        ipAddress: ctx.ip,
        userAgent: ctx.userAgent,
      })

      return gracePeriod
    }),

  /**
   * Revoke a grace period
   */
  revoke: adminProcedure
    .input(z.object({ id: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const gracePeriod = await ctx.prisma.gracePeriod.delete({
        where: { id: input.id },
      })

      // Audit log
      await logAudit({
        prisma: ctx.prisma,
        userId: ctx.user.id,
        action: 'REVOKE_GRACE_PERIOD',
        entityType: 'GracePeriod',
        entityId: input.id,
        detailsJson: {
          userId: gracePeriod.userId,
          roundId: gracePeriod.roundId,
        },
        ipAddress: ctx.ip,
        userAgent: ctx.userAgent,
      })

      return gracePeriod
    }),

  /**
   * Bulk grant grace periods
   */
  bulkGrant: adminProcedure
    .input(
      z.object({
        roundId: z.string(),
        userIds: z.array(z.string()),
        extendedUntil: z.date(),
        reason: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const created = await ctx.prisma.gracePeriod.createMany({
        data: input.userIds.map((userId) => ({
          roundId: input.roundId,
          userId,
          extendedUntil: input.extendedUntil,
          reason: input.reason,
          grantedById: ctx.user.id,
        })),
        skipDuplicates: true,
      })

      // Audit log
      await logAudit({
        prisma: ctx.prisma,
        userId: ctx.user.id,
        action: 'BULK_GRANT_GRACE_PERIOD',
        entityType: 'GracePeriod',
        detailsJson: {
          roundId: input.roundId,
          userCount: input.userIds.length,
          created: created.count,
        },
        ipAddress: ctx.ip,
        userAgent: ctx.userAgent,
      })

      return { created: created.count }
    }),
})
