// Pterodactyl Application API Wrapper

const PTERO_URL = process.env.PTERODACTYL_URL || 'https://panel.example.com'
const PTERO_ADMIN_KEY = process.env.PTERODACTYL_ADMIN_KEY || ''
// const PTERO_CLIENT_KEY = process.env.PTERODACTYL_CLIENT_KEY || ''

interface PteroUser {
  id: number
  username: string
  email: string
  first_name: string
  last_name: string
}

interface CreateServerParams {
  name: string
  userId: number
  eggId: number
  nestId: number
  locationId: number
  memory: number
  disk: number
  cpu: number
  databases: number
  backups: number
  allocations: number
  image: string
  startup?: string
}

async function fetchAdmin(endpoint: string, options: RequestInit = {}) {
  const url = `${PTERO_URL}/api/application${endpoint}`
  const headers = {
    'Authorization': `Bearer ${PTERO_ADMIN_KEY}`,
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    ...(options.headers || {})
  }

  const res = await fetch(url, { ...options, headers })
  
  if (!res.ok) {
    let errorMsg = res.statusText
    try {
      const data = await res.json()
      if (data.errors && data.errors.length > 0) {
        errorMsg = data.errors.map((e: any) => e.detail || e.code).join(', ')
      }
    } catch (e) {}
    throw new Error(`Pterodactyl API Error (${res.status}): ${errorMsg}`)
  }

  if (res.status === 204) return null
  return res.json()
}

export async function getPteroUserByEmail(email: string): Promise<PteroUser | null> {
  const data = await fetchAdmin(`/users?filter[email]=${encodeURIComponent(email)}`)
  if (data && data.data && data.data.length > 0) {
    return data.data[0].attributes
  }
  return null
}

export async function createPteroUser(email: string, username: string, firstName: string, lastName: string, password?: string): Promise<PteroUser> {
  // Check if username exists, if so append random
  const existingUser = await fetchAdmin(`/users?filter[username]=${encodeURIComponent(username)}`)
  let finalUsername = username
  if (existingUser && existingUser.data && existingUser.data.length > 0) {
    finalUsername = `${username}_${Math.floor(Math.random() * 10000)}`
  }

  const body: any = {
    email,
    username: finalUsername,
    first_name: firstName,
    last_name: lastName || 'User'
  }
  
  if (password) {
    body.password = password
  }

  const data = await fetchAdmin('/users', {
    method: 'POST',
    body: JSON.stringify(body)
  })

  return data.attributes
}

export async function createPteroServer(params: CreateServerParams) {
  // 1. Fetch egg details to get required environment variables and startup command
  let envVars: Record<string, string> = {}
  let defaultStartup = ''
  try {
    const eggData = await fetchAdmin(`/nests/${params.nestId}/eggs/${params.eggId}?include=variables`)
    if (eggData && eggData.attributes) {
      defaultStartup = eggData.attributes.startup || ''
      if (eggData.attributes.relationships && eggData.attributes.relationships.variables) {
        const variables = eggData.attributes.relationships.variables.data
        for (const v of variables) {
          const envName = v.attributes.env_variable
          const defaultValue = v.attributes.default_value
          envVars[envName] = defaultValue !== null ? String(defaultValue) : ''
        }
      }
    }
  } catch (error) {
    console.warn('[PTERO] Failed to fetch egg variables, using fallbacks', error)
  }

  // Override specific known variables
  if ('SERVER_MEMORY' in envVars || !Object.keys(envVars).length) envVars['SERVER_MEMORY'] = params.memory.toString()
  if ('SERVER_IP' in envVars || !Object.keys(envVars).length) envVars['SERVER_IP'] = '0.0.0.0'
  if ('SERVER_PORT' in envVars || !Object.keys(envVars).length) envVars['SERVER_PORT'] = '25565'

  const body = {
    name: params.name,
    user: params.userId,
    egg: params.eggId,
    docker_image: params.image,
    startup: params.startup || defaultStartup || ' ', // Pterodactyl requires this field

    environment: envVars,
    limits: {
      memory: params.memory,
      swap: 0,
      disk: params.disk,
      io: 500,
      cpu: params.cpu
    },
    feature_limits: {
      databases: params.databases,
      backups: params.backups,
      allocations: params.allocations
    },
    deploy: {
      locations: [params.locationId],
      dedicated_ip: false,
      port_range: []
    }
  }

  const data = await fetchAdmin('/servers', {
    method: 'POST',
    body: JSON.stringify(body)
  })

  return data.attributes
}

export async function suspendPteroServer(serverId: number) {
  await fetchAdmin(`/servers/${serverId}/suspend`, { method: 'POST' })
}

export async function unsuspendPteroServer(serverId: number) {
  await fetchAdmin(`/servers/${serverId}/unsuspend`, { method: 'POST' })
}

export async function deletePteroServer(serverId: number) {
  await fetchAdmin(`/servers/${serverId}`, { method: 'DELETE' })
}
