const API_BASE = '/api/v1'

export async function apiRequest<T>(
  path: string,
  options: RequestInit = {}
): Promise<T> {
  const token = localStorage.getItem('token')
  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    ...(options.headers as Record<string, string>),
  }
  if (token) {
    headers['Authorization'] = `Bearer ${token}`
  }
  const res = await fetch(`${API_BASE}${path}`, { ...options, headers })
  if (res.status === 401) {
    localStorage.removeItem('token')
    window.location.href = '/login'
    throw new Error('Unauthorized')
  }
  if (!res.ok) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.detail || err.message || `HTTP ${res.status}`)
  }
  return res.json()
}

export async function login(username: string, password: string) {
  const form = new FormData()
  form.append('username', username)
  form.append('password', password)
  const res = await fetch(`${API_BASE}/auth/login`, {
    method: 'POST',
    body: form,
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.detail || `Login failed`)
  }
  const data = await res.json()
  localStorage.setItem('token', data.access_token)
  return data
}

export async function createSite(data: { name: string; domains: string[]; path?: string; ps?: string; php_version?: string; force_https?: boolean }) {
  return apiRequest<{ status: boolean; msg: string; id?: number }>('/site/create', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function getSite(siteId: number) {
  return apiRequest<{ id: number; name: string; path: string; status: number; ps: string; project_type: string; php_version: string; force_https: number; domains: string[] }>(
    `/site/${siteId}`
  )
}

export async function updateSite(siteId: number, data: { path?: string; domains?: string[]; ps?: string }) {
  return apiRequest<{ status: boolean; msg: string }>(`/site/${siteId}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  })
}

export async function listSiteRedirects(siteId: number) {
  return apiRequest<{ id: number; source: string; target: string; code: number }[]>(`/site/${siteId}/redirects`)
}

export async function addSiteRedirect(siteId: number, source: string, target: string, code = 301) {
  return apiRequest<{ status: boolean; msg: string; id: number }>(`/site/${siteId}/redirects`, {
    method: 'POST',
    body: JSON.stringify({ source, target, code }),
  })
}

export async function siteGitClone(siteId: number, url: string, branch = 'main') {
  return apiRequest<{ status: boolean; msg: string }>(`/site/${siteId}/git/clone`, {
    method: 'POST',
    body: JSON.stringify({ url, branch }),
  })
}

export async function siteGitPull(siteId: number) {
  return apiRequest<{ status: boolean; msg: string; output?: string }>(`/site/${siteId}/git/pull`, {
    method: 'POST',
  })
}

export async function deleteSiteRedirect(siteId: number, redirectId: number) {
  return apiRequest<{ status: boolean }>(`/site/${siteId}/redirects/${redirectId}`, { method: 'DELETE' })
}

export async function setSiteStatus(siteId: number, status: boolean) {
  return apiRequest<{ status: boolean; msg: string }>(`/site/${siteId}/status`, {
    method: 'POST',
    body: JSON.stringify({ status: status ? 1 : 0 }),
  })
}

export async function applyFirewallRules() {
  return apiRequest<{ status: boolean; msg: string; count: number }>('/firewall/apply', { method: 'POST' })
}

export async function deleteSite(siteId: number) {
  return apiRequest<{ status: boolean; msg: string }>(`/site/${siteId}`, { method: 'DELETE' })
}

export async function createSiteBackup(siteId: number) {
  return apiRequest<{ status: boolean; msg: string; filename: string }>(`/site/${siteId}/backup`, { method: 'POST' })
}

export async function listSiteBackups(siteId: number) {
  return apiRequest<{ backups: { filename: string; size: number }[] }>(`/site/${siteId}/backups`)
}

export async function restoreSiteBackup(siteId: number, filename: string) {
  return apiRequest<{ status: boolean; msg: string }>(`/site/${siteId}/restore`, {
    method: 'POST',
    body: JSON.stringify({ filename }),
  })
}

export async function downloadSiteBackup(siteId: number, filename: string): Promise<void> {
  const token = localStorage.getItem('token')
  const res = await fetch(`/api/v1/site/${siteId}/backups/download?file=${encodeURIComponent(filename)}`, {
    headers: token ? { Authorization: `Bearer ${token}` } : {},
  })
  if (!res.ok) throw new Error('Download failed')
  const blob = await res.blob()
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  a.click()
  URL.revokeObjectURL(url)
}

export async function listFiles(path: string) {
  return apiRequest<{ path: string; items: { name: string; is_dir: boolean; size: number }[] }>(
    `/files/list?path=${encodeURIComponent(path)}`
  )
}

export async function uploadFile(path: string, file: File) {
  const form = new FormData()
  form.append('path', path)
  form.append('file', file)
  const token = localStorage.getItem('token')
  const res = await fetch('/api/v1/files/upload', {
    method: 'POST',
    headers: token ? { Authorization: `Bearer ${token}` } : {},
    body: form,
  })
  if (!res.ok) {
    const err = await res.json().catch(() => ({}))
    throw new Error(err.detail || 'Upload failed')
  }
  return res.json()
}

export async function readFile(path: string) {
  return apiRequest<{ path: string; content: string }>(`/files/read?path=${encodeURIComponent(path)}`)
}

export async function writeFile(path: string, content: string) {
  return apiRequest<{ status: boolean }>('/files/write', {
    method: 'POST',
    body: JSON.stringify({ path, content }),
  })
}

export async function mkdirFile(path: string, name: string) {
  return apiRequest<{ status: boolean; msg: string }>('/files/mkdir', {
    method: 'POST',
    body: JSON.stringify({ path, name }),
  })
}

export async function renameFile(path: string, oldName: string, newName: string) {
  return apiRequest<{ status: boolean; msg: string }>('/files/rename', {
    method: 'POST',
    body: JSON.stringify({ path, old_name: oldName, new_name: newName }),
  })
}

export async function deleteFile(path: string, name: string, isDir: boolean) {
  return apiRequest<{ status: boolean; msg: string }>('/files/delete', {
    method: 'POST',
    body: JSON.stringify({ path, name, is_dir: isDir }),
  })
}

export async function downloadFile(path: string): Promise<void> {
  const token = localStorage.getItem('token')
  const res = await fetch(`/api/v1/files/download?path=${encodeURIComponent(path)}`, {
    headers: token ? { Authorization: `Bearer ${token}` } : {},
  })
  if (!res.ok) throw new Error('Download failed')
  const blob = await res.blob()
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = path.split('/').pop() || 'download'
  a.click()
  URL.revokeObjectURL(url)
}

export async function listLogs(path: string) {
  return apiRequest<{ path: string; items: { name: string; is_dir: boolean; size: number }[] }>(
    `/logs/list?path=${encodeURIComponent(path)}`
  )
}

export async function readLog(path: string, tail = 1000) {
  return apiRequest<{ path: string; content: string; total_lines: number }>(
    `/logs/read?path=${encodeURIComponent(path)}&tail=${tail}`
  )
}

export async function listSslDomains() {
  return apiRequest<{ id: number; name: string; port: string; site_id: number; site_name: string; site_path: string }[]>(
    '/ssl/domains'
  )
}

export async function requestSslCert(domain: string, webroot: string, email: string) {
  return apiRequest<{ status: boolean }>('/ssl/request', {
    method: 'POST',
    body: JSON.stringify({ domain, webroot, email }),
  })
}

export async function listSslCertificates() {
  return apiRequest<{ certificates: { name: string; path: string }[] }>('/ssl/certificates')
}

export async function nodeAddProcess(script: string, name?: string) {
  return apiRequest<{ status: boolean; msg: string }>('/node/add', {
    method: 'POST',
    body: JSON.stringify({ script, name: name || '' }),
  })
}

export async function listDockerContainers() {
  return apiRequest<{ containers: { id: string; id_full: string; image: string; status: string; names: string; ports: string }[]; error?: string }>(
    '/docker/containers'
  )
}

export async function listDockerImages() {
  return apiRequest<{ images: { repository: string; tag: string; id: string; size: string }[]; error?: string }>(
    '/docker/images'
  )
}

export async function dockerPull(image: string) {
  return apiRequest<{ status: boolean; msg: string }>(`/docker/pull?image=${encodeURIComponent(image)}`, {
    method: 'POST',
  })
}

export async function dockerRun(image: string, name?: string, ports?: string, cmd?: string) {
  return apiRequest<{ status: boolean; msg: string; id?: string }>('/docker/run', {
    method: 'POST',
    body: JSON.stringify({ image, name: name || '', ports: ports || '', cmd: cmd || '' }),
  })
}

export async function dockerStart(containerId: string) {
  return apiRequest<{ status: boolean }>(`/docker/${containerId}/start`, { method: 'POST' })
}

export async function dockerStop(containerId: string) {
  return apiRequest<{ status: boolean }>(`/docker/${containerId}/stop`, { method: 'POST' })
}

export async function dockerRestart(containerId: string) {
  return apiRequest<{ status: boolean }>(`/docker/${containerId}/restart`, { method: 'POST' })
}

export async function createDatabaseBackup(dbId: number) {
  return apiRequest<{ status: boolean; msg: string; filename: string }>(`/database/${dbId}/backup`, {
    method: 'POST',
  })
}

export async function listDatabaseBackups(dbId: number) {
  return apiRequest<{ backups: { filename: string; size: number }[] }>(`/database/${dbId}/backups`)
}

export async function restoreDatabaseBackup(dbId: number, filename: string) {
  return apiRequest<{ status: boolean }>(`/database/${dbId}/restore`, {
    method: 'POST',
    body: JSON.stringify({ filename }),
  })
}

export async function downloadDatabaseBackup(dbId: number, filename: string): Promise<void> {
  const token = localStorage.getItem('token')
  const res = await fetch(
    `/api/v1/database/${dbId}/backups/download?file=${encodeURIComponent(filename)}`,
    { headers: token ? { Authorization: `Bearer ${token}` } : {} }
  )
  if (!res.ok) throw new Error('Download failed')
  const blob = await res.blob()
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = filename
  a.click()
  URL.revokeObjectURL(url)
}

export async function testEmail() {
  return apiRequest<{ status: boolean; msg: string }>('/config/test-email', { method: 'POST' })
}

export async function listUsers() {
  return apiRequest<{ id: number; username: string; email: string; is_active: boolean; is_superuser: boolean }[]>('/user/list')
}

export async function createUser(data: { username: string; password: string; email?: string }) {
  return apiRequest<{ status: boolean; msg: string; id: number }>('/user/create', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function deleteUser(userId: number) {
  return apiRequest<{ status: boolean; msg: string }>(`/user/${userId}`, { method: 'DELETE' })
}

export async function toggleUserActive(userId: number) {
  return apiRequest<{ status: boolean; msg: string; is_active: boolean }>(`/user/${userId}/toggle-active`, { method: 'PUT' })
}

export async function changePassword(oldPassword: string, newPassword: string) {
  return apiRequest<{ message: string }>('/auth/change-password', {
    method: 'POST',
    body: JSON.stringify({ old_password: oldPassword, new_password: newPassword }),
  })
}

export async function listServices() {
  return apiRequest<{ services: { id: string; name: string; unit: string; status: string }[] }>('/service/list')
}

export async function serviceStart(id: string) {
  return apiRequest<{ status: boolean }>(`/service/${id}/start`, { method: 'POST' })
}

export async function serviceStop(id: string) {
  return apiRequest<{ status: boolean }>(`/service/${id}/stop`, { method: 'POST' })
}

export async function serviceRestart(id: string) {
  return apiRequest<{ status: boolean }>(`/service/${id}/restart`, { method: 'POST' })
}

export async function updateFtpPassword(ftpId: number, password: string) {
  return apiRequest<{ status: boolean }>(`/ftp/${ftpId}/password`, {
    method: 'PUT',
    body: JSON.stringify({ password }),
  })
}

export async function updateDatabasePassword(dbId: number, password: string) {
  return apiRequest<{ status: boolean }>(`/database/${dbId}/password`, {
    method: 'PUT',
    body: JSON.stringify({ password }),
  })
}

export async function getDashboardStats() {
  return apiRequest<{
    site_count: number
    ftp_count: number
    database_count: number
    system: {
      cpu_percent: number
      memory_percent: number
      memory_used_mb: number
      memory_total_mb: number
      disk_percent: number
      disk_used_gb: number
      disk_total_gb: number
    }
  }>('/dashboard/stats')
}

export async function applyCrontab() {
  return apiRequest<{ status: boolean; msg: string; count: number }>('/crontab/apply', { method: 'POST' })
}

export async function getMonitorProcesses(limit = 50) {
  return apiRequest<{ processes: { pid: number; name: string; username: string; cpu_percent: number; memory_percent: number; status: string }[] }>(
    `/monitor/processes?limit=${limit}`
  )
}

export async function addPluginFromUrl(url: string) {
  return apiRequest<{ status: boolean; msg: string; id: string }>('/plugin/add-from-url', {
    method: 'POST',
    body: JSON.stringify({ url }),
  })
}

export async function deletePlugin(pluginId: string) {
  return apiRequest<{ status: boolean; msg: string }>(`/plugin/${encodeURIComponent(pluginId)}`, { method: 'DELETE' })
}

export async function getMonitorNetwork() {
  return apiRequest<{ bytes_sent: number; bytes_recv: number; bytes_sent_mb: number; bytes_recv_mb: number }>('/monitor/network')
}

export async function listBackupPlans() {
  return apiRequest<{ id: number; name: string; plan_type: string; target_id: number; schedule: string; enabled: boolean }[]>('/backup/plans')
}

export async function createBackupPlan(data: { name: string; plan_type: string; target_id: number; schedule: string; enabled?: boolean }) {
  return apiRequest<{ status: boolean; msg: string; id: number }>('/backup/plans', {
    method: 'POST',
    body: JSON.stringify(data),
  })
}

export async function updateBackupPlan(planId: number, data: { name: string; plan_type: string; target_id: number; schedule: string; enabled?: boolean }) {
  return apiRequest<{ status: boolean; msg: string }>(`/backup/plans/${planId}`, {
    method: 'PUT',
    body: JSON.stringify(data),
  })
}

export async function deleteBackupPlan(planId: number) {
  return apiRequest<{ status: boolean; msg: string }>(`/backup/plans/${planId}`, { method: 'DELETE' })
}

export async function runScheduledBackups() {
  return apiRequest<{ status: boolean; results: { plan: string; status: string; msg?: string }[] }>('/backup/run-scheduled', { method: 'POST' })
}
