import { z } from 'zod'
import { router, protectedProcedure } from '../trpc'
import { generateAvatarKey, type StorageProviderType } from '@/lib/storage'
import {
  getImageUploadUrl,
  confirmImageUpload,
  getImageUrl,
  deleteImage,
  type ImageUploadConfig,
} from '../utils/image-upload'

type AvatarSelect = {
  profileImageKey: string | null
  profileImageProvider: string | null
}

const avatarConfig: ImageUploadConfig<AvatarSelect> = {
  label: 'avatar',
  generateKey: generateAvatarKey,
  findCurrent: (prisma, entityId) =>
    prisma.user.findUnique({
      where: { id: entityId },
      select: { profileImageKey: true, profileImageProvider: true },
    }),
  getImageKey: (record) => record.profileImageKey,
  getProviderType: (record) =>
    (record.profileImageProvider as StorageProviderType) || 's3',
  setImage: (prisma, entityId, key, providerType) =>
    prisma.user.update({
      where: { id: entityId },
      data: { profileImageKey: key, profileImageProvider: providerType },
    }),
  clearImage: (prisma, entityId) =>
    prisma.user.update({
      where: { id: entityId },
      data: { profileImageKey: null, profileImageProvider: null },
    }),
  auditEntityType: 'User',
  auditFieldName: 'profileImageKey',
}

export const avatarRouter = router({
  /**
   * Get a pre-signed URL for uploading an avatar
   */
  getUploadUrl: protectedProcedure
    .input(
      z.object({
        fileName: z.string(),
        contentType: z.string(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      return getImageUploadUrl(
        ctx.user.id,
        input.fileName,
        input.contentType,
        generateAvatarKey
      )
    }),

  /**
   * Confirm avatar upload and update user profile
   */
  confirmUpload: protectedProcedure
    .input(
      z.object({
        key: z.string(),
        providerType: z.enum(['s3', 'local']),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const userId = ctx.user.id

      await confirmImageUpload(ctx.prisma, avatarConfig, userId, input.key, input.providerType, {
        userId: ctx.user.id,
        ip: ctx.ip,
        userAgent: ctx.userAgent,
      })

      // Return the updated user fields to match original API contract
      const user = await ctx.prisma.user.findUnique({
        where: { id: userId },
        select: {
          id: true,
          profileImageKey: true,
          profileImageProvider: true,
        },
      })

      return user
    }),

  /**
   * Get the current user's avatar URL
   */
  getUrl: protectedProcedure.query(async ({ ctx }) => {
    return getImageUrl(ctx.prisma, avatarConfig, ctx.user.id)
  }),

  /**
   * Delete the current user's avatar
   */
  delete: protectedProcedure.mutation(async ({ ctx }) => {
    return deleteImage(ctx.prisma, avatarConfig, ctx.user.id, {
      userId: ctx.user.id,
      ip: ctx.ip,
      userAgent: ctx.userAgent,
    })
  }),
})
