import fs from 'fs'
import os from 'os'
import path from 'path'
import { afterEach, describe, expect, it } from 'vitest'
import {
  assertStorageConfiguration,
  deleteImage,
  getPrivateStorageRoot,
  getProtectedCustomerLicenseImageUrl,
  getPublicStorageRoot,
  getStorageRoot,
  resolveStoredFilePath,
  uploadImage,
} from './storage'

const originalEnv = { ...process.env }

describe('storage', () => {
  afterEach(() => {
    process.env = { ...originalEnv }
  })

  it('uses FILE_STORAGE_ROOT when configured and builds protected customer license URLs from dashboard URL', () => {
    process.env.FILE_STORAGE_ROOT = '/tmp/rdg-storage'
    process.env.DASHBOARD_URL = 'https://dashboard.rentaldrivego.test/dashboard/'

    expect(getStorageRoot()).toBe('/tmp/rdg-storage')
    expect(getPublicStorageRoot()).toBe('/tmp/rdg-storage/public')
    expect(getPrivateStorageRoot()).toBe('/tmp/rdg-storage/private')
    expect(getProtectedCustomerLicenseImageUrl('customer_1')).toBe('https://dashboard.rentaldrivego.test/dashboard/api/v1/customers/customer_1/license-image')
  })

  it('rejects implicit in-app storage in production', () => {
    delete process.env.FILE_STORAGE_ROOT
    process.env.NODE_ENV = 'production'

    expect(() => assertStorageConfiguration()).toThrow('FILE_STORAGE_ROOT must be set in production')
  })

  it('uploads, resolves, and deletes files under the configured storage root', async () => {
    const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rdg-storage-'))
    process.env.FILE_STORAGE_ROOT = root
    process.env.API_URL = 'https://api.rentaldrivego.test/'

    const url = await uploadImage(Buffer.from('image-bytes'), 'customers/licenses', 'customer_1')

    expect(url).toBe('https://api.rentaldrivego.test/storage/customers/licenses/customer_1.jpg')
    const filePath = resolveStoredFilePath(url)
    expect(filePath).toBe(path.join(root, 'private/customers/licenses/customer_1.jpg'))
    expect(fs.readFileSync(filePath!, 'utf8')).toBe('image-bytes')

    await deleteImage(url)
    expect(fs.existsSync(filePath!)).toBe(false)
  })

  it('ignores non-storage URLs when resolving or deleting files', async () => {
    process.env.FILE_STORAGE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'rdg-storage-'))

    expect(resolveStoredFilePath('https://cdn.test/not-storage/file.jpg')).toBeNull()
    await expect(deleteImage('https://cdn.test/not-storage/file.jpg')).resolves.toBeUndefined()
  })
})
