import type { StorageProvider, StorageProviderType } from './types'
import { S3StorageProvider } from './s3-provider'
import { LocalStorageProvider } from './local-provider'
import { prisma } from '@/lib/prisma'

export type { StorageProvider, StorageProviderType } from './types'
export { S3StorageProvider } from './s3-provider'
export { LocalStorageProvider } from './local-provider'

// Cached provider instance
let cachedProvider: StorageProvider | null = null
let cachedProviderType: StorageProviderType | null = null

/**
 * Get the configured storage provider type from system settings
 */
async function getProviderTypeFromSettings(): Promise<StorageProviderType> {
  try {
    const setting = await prisma.systemSettings.findUnique({
      where: { key: 'storage_provider' },
    })
    const value = setting?.value as StorageProviderType | undefined
    return value === 'local' ? 'local' : 's3' // Default to S3
  } catch {
    // If settings table doesn't exist or error, default to S3
    return 's3'
  }
}

/**
 * Get the current storage provider type from settings
 */
export async function getCurrentProviderType(): Promise<StorageProviderType> {
  return getProviderTypeFromSettings()
}

/**
 * Get a storage provider instance based on system settings
 * Caches the provider for performance
 */
export async function getStorageProvider(): Promise<StorageProvider> {
  const providerType = await getProviderTypeFromSettings()

  // Return cached provider if type hasn't changed
  if (cachedProvider && cachedProviderType === providerType) {
    return cachedProvider
  }

  // Create new provider
  if (providerType === 'local') {
    cachedProvider = new LocalStorageProvider()
  } else {
    cachedProvider = new S3StorageProvider()
  }
  cachedProviderType = providerType

  return cachedProvider
}

/**
 * Get a storage provider and its type together
 */
export async function getStorageProviderWithType(): Promise<{
  provider: StorageProvider
  providerType: StorageProviderType
}> {
  const providerType = await getProviderTypeFromSettings()
  const provider = await getStorageProvider()
  return { provider, providerType }
}

/**
 * Create a specific storage provider (bypasses settings)
 */
export function createStorageProvider(type: StorageProviderType): StorageProvider {
  if (type === 'local') {
    return new LocalStorageProvider()
  }
  return new S3StorageProvider()
}

/**
 * Clear the cached provider (call when settings change)
 */
export function clearStorageProviderCache(): void {
  cachedProvider = null
  cachedProviderType = null
}

/**
 * Generate a unique storage key for avatars
 */
export function generateAvatarKey(userId: string, fileName: string): string {
  const timestamp = Date.now()
  const ext = fileName.split('.').pop() || 'jpg'
  return `avatars/${userId}/${timestamp}.${ext}`
}

/**
 * Generate a unique storage key for project logos
 */
export function generateLogoKey(projectId: string, fileName: string): string {
  const timestamp = Date.now()
  const ext = fileName.split('.').pop() || 'png'
  return `logos/${projectId}/${timestamp}.${ext}`
}

/**
 * Get content type from file extension
 */
export function getContentType(fileName: string): string {
  const ext = fileName.toLowerCase().split('.').pop()
  const types: Record<string, string> = {
    jpg: 'image/jpeg',
    jpeg: 'image/jpeg',
    png: 'image/png',
    gif: 'image/gif',
    webp: 'image/webp',
    svg: 'image/svg+xml',
    pdf: 'application/pdf',
  }
  return types[ext || ''] || 'application/octet-stream'
}

/**
 * Validate image file type
 */
export function isValidImageType(contentType: string): boolean {
  const validTypes = [
    'image/jpeg',
    'image/jpg', // non-standard but common browser alias for image/jpeg
    'image/png',
    'image/gif',
    'image/webp',
    'image/svg+xml',
    'application/octet-stream', // some browsers send this as a fallback
  ]
  return validTypes.includes(contentType)
}
