import type { Endpoint } from 'payload'
import { Storage } from '@google-cloud/storage'
import path from 'path'
import { fileURLToPath } from 'url'
import { gcsConfig } from '@/utilities/gcsConfig'

const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)

// Only enabled in non-production
const isDebugAllowed = process.env.NODE_ENV !== 'production'

export const debugGcsEndpoint: Endpoint = {
  path: '/debug-gcs',
  method: ['get', 'post'],
  handler: async (req) => {
    if (!isDebugAllowed) {
      return Response.json({ error: 'Not available in production' }, { status: 403 })
    }

    // Must be logged in
    if (!req.user) {
      return Response.json({ error: 'Unauthorized' }, { status: 401 })
    }

    const keyFilename = path.resolve(dirname, '../../gcs-credentials.json')
    const keepFile = req.searchParams.get('keep') === 'true'
    
    // Handle POST for manual file upload test
    if (req.method === 'POST') {
      try {
        const formData = await req.formData()
        const fileData = formData.get('file') as File
        
        if (!fileData) {
          return Response.json({ error: 'No file provided in field "file"' }, { status: 400 })
        }

        const storage = new Storage({
          projectId: process.env.GCS_PROJECT_ID || '',
          keyFilename,
        })

        const bucket = storage.bucket(gcsConfig.bucket)
        const destination = `${gcsConfig.prefix}/manual-api-test-${Date.now()}-${fileData.name}`
        const gcsFile = bucket.file(destination)
        
        const buffer = Buffer.from(await fileData.arrayBuffer())
        
        await gcsFile.save(buffer, {
          contentType: fileData.type,
          metadata: { cacheControl: 'no-cache' },
        })

        return Response.json({
          success: true,
          message: 'Manual upload success',
          destination,
          url: `${gcsConfig.bucketBaseURL}/${destination}`,
        })
      } catch (uploadErr: any) {
        return Response.json({
          success: false,
          error: uploadErr.message,
          stack: uploadErr.stack,
        }, { status: 500 })
      }
    }
    
    const results: Record<string, any> = {
      timestamp: new Date().toISOString(),
      resolvedKeyFilename: keyFilename,
      config: {
        bucket: gcsConfig.bucket,
        prefix: gcsConfig.prefix,
        bucketBaseURL: gcsConfig.bucketBaseURL,
        USE_GCS: process.env.USE_GCS,
        GCS_PROJECT_ID: process.env.GCS_PROJECT_ID,
      },
      diagnostics: {},
    }

    try {
      const storage = new Storage({
        projectId: process.env.GCS_PROJECT_ID || '',
        keyFilename,
      })

      // 1. Check bucket exists and is accessible
      const bucket = storage.bucket(gcsConfig.bucket)
      const [metadata] = await bucket.getMetadata()
      results.diagnostics.bucketMetadata = {
        name: metadata.name,
        location: metadata.location,
        iamConfiguration: metadata.iamConfiguration,
      }
      results.diagnostics.bucketAccessible = true

      // 2. Try a test upload
      const testFileName = `${gcsConfig.prefix}/__api-test-${Date.now()}.txt`
      const file = bucket.file(testFileName)
      
      const testData = `GCS Diagnostic Test\nTime: ${new Date().toISOString()}\nBucket: ${gcsConfig.bucket}`
      
      await file.save(testData, {
        contentType: 'text/plain',
        metadata: { cacheControl: 'no-cache' },
      })
        results.diagnostics.uploadSuccess = true
        results.diagnostics.testFilePath = testFileName
        results.diagnostics.testFileURL = `${gcsConfig.bucketBaseURL}/${testFileName}`

        // 3. Inspect Payload Config for Storage Integration
        const mediaCollection = req.payload.config.collections.find(c => c.slug === 'media')
        results.diagnostics.payloadIntegration = {
          foundMediaCollection: !!mediaCollection,
          disableLocalStorage: mediaCollection?.upload?.disableLocalStorage,
          // Check if afterRead hooks include a storage-related hook
          hasAfterReadHooks: !!mediaCollection?.hooks?.afterRead?.length,
        }
      results.diagnostics.ublaDetection = {
        status: 'Checking...',
      }
      
      try {
        await file.makePublic()
        results.diagnostics.ublaDetection.status = 'ACLs Supported (makePublic worked)'
        results.diagnostics.ublaDetection.ublaEnabled = false
      } catch (aclErr: any) {
        if (aclErr.message?.includes('uniform bucket-level access')) {
          results.diagnostics.ublaDetection.status = 'UBLA Enabled (Detected via ACL error)'
          results.diagnostics.ublaDetection.ublaEnabled = true
          results.diagnostics.ublaDetection.details = aclErr.message
        } else {
          results.diagnostics.ublaDetection.status = `ACL Error: ${aclErr.message}`
        }
      }

      // 4. Clean up unless 'keep' is true
      if (!keepFile) {
        await file.delete()
        results.diagnostics.testFileDeleted = true
      } else {
        results.diagnostics.testFileDeleted = false
        results.diagnostics.instructions = 'File kept for manual verification. Visit the testFileURL to check accessibility.'
      }

    } catch (err: any) {
      results.error = {
        message: err.message,
        stack: err.stack,
        code: err.code,
      }
      results.diagnostics.bucketAccessible = false
    }

    return Response.json(results, { status: 200 })
  },
}
