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

type LogoSelect = {
  logoKey: string | null
  logoProvider: string | null
}

const logoConfig: ImageUploadConfig<LogoSelect> = {
  label: 'logo',
  generateKey: generateLogoKey,
  findCurrent: (prisma, entityId) =>
    prisma.project.findUnique({
      where: { id: entityId },
      select: { logoKey: true, logoProvider: true },
    }),
  getImageKey: (record) => record.logoKey,
  getProviderType: (record) =>
    (record.logoProvider as StorageProviderType) || 's3',
  setImage: (prisma, entityId, key, providerType) =>
    prisma.project.update({
      where: { id: entityId },
      data: { logoKey: key, logoProvider: providerType },
    }),
  clearImage: (prisma, entityId) =>
    prisma.project.update({
      where: { id: entityId },
      data: { logoKey: null, logoProvider: null },
    }),
  auditEntityType: 'Project',
  auditFieldName: 'logoKey',
}

export const logoRouter = router({
  /**
   * Get a pre-signed URL for uploading a project logo
   */
  getUploadUrl: adminProcedure
    .input(
      z.object({
        projectId: z.string(),
        fileName: z.string(),
        contentType: z.string(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      // Verify project exists
      const project = await ctx.prisma.project.findUnique({
        where: { id: input.projectId },
        select: { id: true },
      })

      if (!project) {
        throw new TRPCError({ code: 'NOT_FOUND', message: 'Project not found' })
      }

      return getImageUploadUrl(
        input.projectId,
        input.fileName,
        input.contentType,
        generateLogoKey
      )
    }),

  /**
   * Confirm logo upload and update project
   */
  confirmUpload: adminProcedure
    .input(
      z.object({
        projectId: z.string(),
        key: z.string(),
        providerType: z.enum(['s3', 'local']),
      })
    )
    .mutation(async ({ ctx, input }) => {
      await confirmImageUpload(
        ctx.prisma,
        logoConfig,
        input.projectId,
        input.key,
        input.providerType,
        {
          userId: ctx.user.id,
          ip: ctx.ip,
          userAgent: ctx.userAgent,
        }
      )

      // Return the updated project fields to match original API contract
      const project = await ctx.prisma.project.findUnique({
        where: { id: input.projectId },
        select: {
          id: true,
          logoKey: true,
          logoProvider: true,
        },
      })

      return project
    }),

  /**
   * Get a project's logo URL (any authenticated user — logos are public display data)
   */
  getUrl: protectedProcedure
    .input(z.object({ projectId: z.string() }))
    .query(async ({ ctx, input }) => {
      return getImageUrl(ctx.prisma, logoConfig, input.projectId)
    }),

  /**
   * Delete a project's logo
   */
  delete: adminProcedure
    .input(z.object({ projectId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      return deleteImage(ctx.prisma, logoConfig, input.projectId, {
        userId: ctx.user.id,
        ip: ctx.ip,
        userAgent: ctx.userAgent,
      })
    }),
})
