import color from 'kleur'
import { del, get, handleError, post } from '../http'
import { resolveAppName } from '../name'

interface EnvVar {
  key: string
  value: string
}

function parseKeyValue(keyOrKeyValue: string, valueArg?: string): { key: string, value: string } | null {
  if (valueArg !== undefined) {
    const key = keyOrKeyValue.trim()
    if (!key) { console.error('Key cannot be empty'); return null }
    return { key, value: valueArg }
  }
  const eqIndex = keyOrKeyValue.indexOf('=')
  if (eqIndex === -1) {
    console.error('Invalid format. Use: KEY value or KEY=value')
    return null
  }
  const key = keyOrKeyValue.slice(0, eqIndex).trim()
  if (!key) { console.error('Key cannot be empty'); return null }
  return { key, value: keyOrKeyValue.slice(eqIndex + 1) }
}

async function globalEnvSet(keyOrKeyValue: string, valueArg?: string) {
  const parsed = parseKeyValue(keyOrKeyValue, valueArg)
  if (!parsed) return
  const { key, value } = parsed

  try {
    const result = await post<{ ok: boolean, error?: string }>('/api/env', { key, value })
    if (result?.ok) {
      console.log(color.green(`Set global ${color.bold(key.toUpperCase())}`))
    } else {
      console.error(result?.error ?? 'Failed to set variable')
    }
  } catch (error) {
    handleError(error)
  }
}

export async function envList(name: string | undefined, opts: { global?: boolean }) {
  if (opts.global) {
    const vars = await get<EnvVar[]>('/api/env')
    console.log(color.bold().cyan('Global Environment Variables'))
    console.log()
    if (!vars || vars.length === 0) {
      console.log(color.gray('  No global environment variables set'))
      return
    }
    for (const v of vars) {
      console.log(`  ${color.bold(v.key)}=${color.gray(v.value)}`)
    }
    return
  }

  const appName = resolveAppName(name)
  if (!appName) return

  const [vars, globalVars] = await Promise.all([
    get<EnvVar[]>(`/api/apps/${appName}/env`),
    get<EnvVar[]>('/api/env'),
  ])

  if (!vars) {
    console.error(`App not found: ${appName}`)
    return
  }

  console.log(color.bold().cyan(`Environment Variables for ${appName}`))
  console.log()

  const appKeys = new Set(vars.map(v => v.key))

  if (vars.length === 0 && (!globalVars || globalVars.length === 0)) {
    console.log(color.gray('  No environment variables set'))
    return
  }

  for (const v of vars) {
    console.log(`  ${color.bold(v.key)}=${color.gray(v.value)}`)
  }

  if (globalVars && globalVars.length > 0) {
    const inherited = globalVars.filter(v => !appKeys.has(v.key))
    if (inherited.length > 0) {
      if (vars.length > 0) console.log()
      console.log(color.gray('  Inherited from global:'))
      for (const v of inherited) {
        console.log(`  ${color.bold(v.key)}=${color.gray(v.value)}`)
      }
    }
  }
}

export async function envSet(name: string | undefined, keyOrKeyValue: string, valueArg: string | undefined, opts: { global?: boolean }) {
  // With --global, args shift: name becomes key, key becomes value
  if (opts.global) {
    const actualKey = name ?? keyOrKeyValue
    const actualValue = name ? keyOrKeyValue : valueArg
    return globalEnvSet(actualKey, actualValue)
  }

  const parsed = parseKeyValue(keyOrKeyValue, valueArg)
  if (!parsed) return
  const { key, value } = parsed

  const appName = resolveAppName(name)
  if (!appName) return

  try {
    const result = await post<{ ok: boolean, error?: string }>(`/api/apps/${appName}/env`, { key, value })
    if (result?.ok) {
      console.log(color.green(`Set ${color.bold(key.toUpperCase())} for ${appName}`))
      console.log(color.gray('App restarted to apply changes'))
    } else {
      console.error(result?.error ?? 'Failed to set variable')
    }
  } catch (error) {
    handleError(error)
  }
}

export async function envRm(name: string | undefined, key: string, opts: { global?: boolean }) {
  // With --global, args shift: name becomes key
  if (opts.global) {
    const actualKey = name ?? key
    if (!actualKey) {
      console.error('Key is required')
      return
    }
    const ok = await del(`/api/env/${actualKey.toUpperCase()}`)
    if (ok) {
      console.log(color.green(`Removed global ${color.bold(actualKey.toUpperCase())}`))
    }
    return
  }

  if (!key) {
    console.error('Key is required')
    return
  }

  const appName = resolveAppName(name)
  if (!appName) return

  const ok = await del(`/api/apps/${appName}/env/${key.toUpperCase()}`)
  if (ok) {
    console.log(color.green(`Removed ${color.bold(key.toUpperCase())} from ${appName}`))
    console.log(color.gray('App restarted to apply changes'))
  }
}
