import client from "./client"
import type { ApiResponse } from "../types"

export interface ServerItem {
  id: number
  status: string
  hostname: string | null
  main_ip: string | null
  ssh_port: number | null
  os_image: string | null
  os_name: string | null
  expires_at: string | null
  created_at: string | null
  product_name: string
  product_group_name: string | null
  product_group_area?: number | null
  product_group_node?: number | null
  product_group_network_type?: string | null
  cpu: number | null
  memory: number | null
  upstream_id: number | null
  upstream_power: string | null
  cycle: string
  unit_price: number
  next_renew_amount: number
  auto_renew: number
  system_disk_size: number | null
  data_disk_size: number | null
  in_bw: number | null
  out_bw: number | null
  internet: number
  nat_acl_limit?: number | null
  nat_web_limit?: number | null
  is_locked: number
  suspend_type: string | null
  security_group_id?: string | number | null
  security_group_name?: string | null
  api_type?: string | null
  provision_plugin?: ServerProvisionPlugin | null
  plugin_manage_actions?: ServerPluginManageAction[]
  plugin_links?: ServerPluginLink[]
}

export interface ServerPluginManageAction {
  key: string
  label: string
  confirm?: boolean
  style?: "default" | "primary" | "danger" | string
  audience?: "user" | "admin" | "both" | string
  description?: string
}

export interface ServerPluginLink {
  label: string
  url: string
}

export interface ServerProvisionProductPageTab {
  key: string
  label: string
  html: string
}

export interface ServerProvisionProductPage {
  layout?: string
  summary_html?: string
  empty_state_html?: string
  tabs?: ServerProvisionProductPageTab[]
  purchase_fields?: { key: string; label: string; type: string; required?: boolean; placeholder?: string }[]
}

export interface ServerProvisionPlugin {
  id: string
  name: string
  version: string
  description?: string
  product_page?: ServerProvisionProductPage
  manage_page?: ServerProvisionProductPage
}

export interface PointReward {
  id: number
  order_id: number
  instance_id: number | null
  source_type: string
  status: "pending" | "claimable" | "claimed" | "cancelled" | "reversed" | string
  status_label: string
  amount_cents: number
  reward_rate: number
  points: number
  ref_no: string | null
  remark: string | null
  created_at: string | null
  claimed_at: string | null
}

export interface ServerConfigField {
  def: string
  type: "fixed" | "user_select" | "input" | "slider"
  value?: string | number | null
  options?: { def: string }[]
  validation?: string
  hostname_prefix?: string
  hostname_length?: string
  slider_min?: number
  slider_max?: number
  slider_step?: number
  slider_unit_price?: number
  slider_unit?: string
}

export interface ServerOsOption {
  label?: string
  value: number | string
  [key: string]: unknown
}

export interface ServerDetail extends ServerItem {
  upstream?: {
    provider?: string | null
    disk?: UpstreamDisk[]
    delete_with_host?: number | string | null
    create_with_host?: number | string | null
    [key: string]: unknown
  }
  upstream_error?: string
  root_password?: string
  provision_config?: ServerConfigField[]
  os_options?: ServerOsOption[]
  point_rewards?: PointReward[]
}

export interface UpstreamDisk {
  id?: number | string | null
  type?: string | null
  size?: number | string | null
  status?: number | string | null
  dev?: string | null
  io?: string | null
  driver?: string | null
  cache?: string | null
  create_time?: string | null
  name?: string | null
  fs_type?: string | null
  remarks?: string | null
  read_bytes_sec?: number | string | null
  write_bytes_sec?: number | string | null
  read_iops_sec?: number | string | null
  write_iops_sec?: number | string | null
  read_bytes_sec_max?: number | string | null
  write_bytes_sec_max?: number | string | null
  read_iops_sec_max?: number | string | null
  write_iops_sec_max?: number | string | null
  iops_min?: number | string | null
  iops_max?: number | string | null
  store_type?: string | null
  store_name?: string | null
  store_id?: string | null
  real_dir?: string | null
  real_size?: number | string | null
  delete_with_host?: number | string | null
  create_with_host?: number | string | null
  snap_num?: number | string | null
  enable_node?: unknown
}

export interface OperateResult {
  taskid: number | null
  instance_id?: number
}

export function listServers() {
  return client.get<ApiResponse<ServerItem[]>>("/v1/instances")
}

export function getServer(id: number) {
  return client.get<ApiResponse<ServerDetail>>(`/v1/instances/${id}`)
}

export function powerOn(id: number) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/power-on`)
}

export function shutdown(id: number) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/shutdown`)
}

export function hardShutdown(id: number) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/hard-shutdown`)
}

export function reboot(id: number) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/reboot`)
}

export function runPluginAction(id: number, action: string, payload: Record<string, unknown> = {}) {
  return client.post<ApiResponse<Record<string, unknown>>>(`/v1/instances/${id}/plugin-actions/${action}`, {
    payload,
  })
}

export function suspendInstance(id: number, type: "traffic" | "due" = "due", freeGpu = 0) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/suspend`, {
    type,
    free_gpu: freeGpu,
  })
}

export function unsuspendInstance(id: number) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/unsuspend`)
}

export function deleteInstance(id: number) {
  return client.delete<ApiResponse<OperateResult>>(`/v1/instances/${id}`)
}

export function resetPassword(id: number, password: string) {
  return client.post<ApiResponse<OperateResult>>(`/v1/instances/${id}/reset-password`, { password })
}

export interface ReinstallPayload {
  os: number
  password?: string
  format_data_disk?: 0 | 1
}

export interface ReinstallResult {
  taskid: number | null
  user?: string | null
  password?: string | null
  port?: number | string | null
  system_disk_size?: number | string | null
}

export function reinstallInstance(id: number, payload: ReinstallPayload) {
  return client.put<ApiResponse<ReinstallResult>>(`/v1/instances/${id}/reinstall`, payload)
}

export interface DiskCreatePayload {
  size: number
}

export interface DiskResizePayload {
  size: number
}

export interface DiskCreateResult {
  taskid: number | null
  diskid: number | null
  order_id: number
  order_no: string
  amount: number
  recurring_amount: number
  balance: number
  next_renew_amount: number
}

export interface DiskResizeResult extends DiskCreateResult {
  source_size: number
  target_size: number
  delta_size: number
}

export interface DiskDetachResult {
  taskid: number | null
  diskid: number | string
  message?: string
}

export interface DiskMountResult {
  taskid: number | null
  diskid: number | string
  message?: string
}

export interface DiskDeleteResult {
  taskid: number | null
  diskid: number | string
  removed_recurring_amount: number
  next_renew_amount: number
}

export interface DiskQuoteResult {
  size: number
  billable_size: number
  cycle: string
  recurring_amount: number
  current_charge: number
  remaining_days: number
  charged_until: string | null
  expires_at: string | null
  unit_price_cents: number
  next_renew_amount: number
  diskid?: number
  source_size?: number
  target_size?: number
  delta_size?: number
}

export function addDisk(id: number, payload: DiskCreatePayload) {
  return client.post<ApiResponse<DiskCreateResult>>(`/v1/instances/${id}/disks`, payload)
}

export function quoteDisk(id: number, payload: DiskCreatePayload) {
  return client.post<ApiResponse<DiskQuoteResult>>(`/v1/instances/${id}/disks/quote`, payload)
}

export function quoteResizeDisk(instanceId: number, diskId: number | string, payload: DiskResizePayload) {
  return client.post<ApiResponse<DiskQuoteResult>>(
    `/v1/instances/${instanceId}/disks/${diskId}/resize/quote`,
    payload,
  )
}

export function resizeDisk(instanceId: number, diskId: number | string, payload: DiskResizePayload) {
  return client.put<ApiResponse<DiskResizeResult>>(
    `/v1/instances/${instanceId}/disks/${diskId}/resize`,
    payload,
  )
}

export function mountDisk(instanceId: number, diskId: number | string) {
  return client.post<ApiResponse<DiskMountResult>>(
    `/v1/instances/${instanceId}/disks/${diskId}/mount`,
  )
}

export function detachDisk(instanceId: number, diskId: number | string) {
  return client.delete<ApiResponse<DiskDetachResult>>(
    `/v1/instances/${instanceId}/disks/${diskId}/detach`,
  )
}

export function deleteDisk(instanceId: number, diskId: number | string) {
  return client.delete<ApiResponse<DiskDeleteResult>>(
    `/v1/instances/${instanceId}/disks/${diskId}`,
  )
}

export interface RenewInstanceResult {
  order_id: number
  order_no: string
  amount: number
  balance: number
  expires_at: string
}

export function renewInstance(id: number, cycles: number) {
  return client.post<ApiResponse<RenewInstanceResult>>(`/v1/instances/${id}/renew`, { cycles })
}

export interface UpdateAutoRenewResult {
  id: number
  auto_renew: number
}

export function updateAutoRenew(id: number, autoRenew: boolean) {
  return client.patch<ApiResponse<UpdateAutoRenewResult>>(`/v1/instances/${id}/auto-renew`, {
    auto_renew: autoRenew,
  })
}

export interface ClaimServerPointsResult {
  claimed_points: number
  claimed_count: number
  pending_count: number
}

export function claimServerPoints(id: number) {
  return client.post<ApiResponse<ClaimServerPointsResult>>(`/v1/instances/${id}/points/claim`)
}

export interface InstanceNatAclItem {
  id: number | null
  name: string
  description: string
  ext_port: number | null
  int_port: number | null
  int_ip?: string | null
  protocol: number | null
}

export interface InstanceNatAclMeta {
  total: number
  total_page: number
  page: number
  per_page: number
}

export interface InstanceNatAclList {
  list: InstanceNatAclItem[]
  meta: InstanceNatAclMeta
  nat_host_ip: string | null
}

export interface InstanceNatAclQuery {
  page?: number
  per_page?: number
  orderby?: "id" | "name" | "ext_port" | "int_port" | "protocol"
  sort?: "asc" | "desc"
  search?: string
  list_type?: "all" | "page"
}

export interface InstanceNatAclPayload {
  name: string
  ext_port?: number | null
  int_port: number
  protocol: 1 | 2 | 3
}

export function listInstanceNatAcl(instanceId: number, params: InstanceNatAclQuery = {}) {
  return client.get<ApiResponse<InstanceNatAclList>>(
    `/v1/instances/${instanceId}/nat-acl`,
    { params },
  )
}

export function createInstanceNatAcl(instanceId: number, payload: InstanceNatAclPayload) {
  return client.post<ApiResponse<InstanceNatAclItem>>(`/v1/instances/${instanceId}/nat-acl`, payload)
}

export function deleteInstanceNatAcl(instanceId: number, natAclId: number) {
  return client.delete<ApiResponse<Record<string, unknown>>>(`/v1/instances/${instanceId}/nat-acl/${natAclId}`)
}

export interface InstanceRealData {
  id?: number
  instance_id?: number
  kvm?: string | null
  cpu_usage?: number | string | null
  memory_usage?: number | string | null
  memory_total?: string | null
  memory_usable?: string | null
  current_in_bw?: string | null
  current_out_bw?: string | null
  current_read_byte?: number | string | null
  current_write_byte?: number | string | null
  collected_at?: string | null
}

export function getInstanceRealData(instanceId: number) {
  return client.get<ApiResponse<InstanceRealData>>(`/v1/instances/${instanceId}/real-data`)
}

export function getInstanceRealDataHistory(instanceId: number) {
  return client.get<ApiResponse<InstanceRealData[]>>(`/v1/instances/${instanceId}/real-data-history`)
}

export interface InstanceSnapshotItem {
  id: number
  size?: number | string | null
  name?: string | null
  type?: "snap" | "backup" | string | null
  create_time?: string | null
  remarks?: string | null
  disk_name?: string | null
  disk_remarks?: string | null
  real_file?: string | null
  status?: number | string | null
  next?: { id?: number | string | null; name?: string | null }[]
}

export interface InstanceSnapshotMeta {
  total: number
  total_page: number
  page: number
  per_page: number
}

export interface InstanceSnapshotList {
  list: InstanceSnapshotItem[]
  meta: InstanceSnapshotMeta
  supported?: boolean
  message?: string
}

export interface InstanceSnapshotQuery {
  page?: number
  per_page?: number
  orderby?: "id" | "size" | "name" | "type"
  sort?: "asc" | "desc"
  search?: string
  type?: "snap" | "backup"
}

export interface InstanceSnapshotCreatePayload {
  type: "snap" | "backup"
  name?: string
  remarks?: string
}

export interface InstanceSnapshotCreateResult {
  taskid: number | null
  diskid: number | string
  type: "snap" | "backup"
}

export interface InstanceSnapshotActionResult {
  taskid: number | null
  snapshot_id: number | string
}

export interface InstanceSnapshotRestoreResult extends InstanceSnapshotActionResult {
  os?: {
    id?: number | string | null
    name?: string | null
    filename?: string | null
    user?: string | null
    password?: string | null
    port?: number | string | null
  } | null
}

export interface InstanceCronSnapshotDisk {
  id: number | string
  name?: string | null
}

export interface InstanceCronSnapshotItem {
  id: number
  hostid?: number | string | null
  type?: "snap" | "backup" | string | null
  frequency?: number | string | null
  cycle?: "hour" | "day" | "week" | "month" | string | null
  create_time?: string | null
  point?: string | null
  disk?: InstanceCronSnapshotDisk[]
}

export interface InstanceCronSnapshotList {
  list: InstanceCronSnapshotItem[]
  supported?: boolean
  message?: string
}

export interface InstanceCronSnapshotCreatePayload {
  type: "snap" | "backup"
  frequency: number
  cycle: "hour" | "day" | "week" | "month"
  disk: number[]
  point?: string
}

export function listInstanceSnapshots(instanceId: number, params: InstanceSnapshotQuery) {
  return client.get<ApiResponse<InstanceSnapshotList>>(
    `/v1/instances/${instanceId}/snapshots`,
    { params },
  )
}

export function createInstanceSnapshot(
  instanceId: number,
  diskId: number | string,
  payload: InstanceSnapshotCreatePayload,
) {
  return client.post<ApiResponse<InstanceSnapshotCreateResult>>(
    `/v1/instances/${instanceId}/disks/${diskId}/snapshots`,
    payload,
  )
}

export function deleteInstanceSnapshot(instanceId: number, snapshotId: number | string) {
  return client.delete<ApiResponse<InstanceSnapshotActionResult>>(
    `/v1/instances/${instanceId}/snapshots/${snapshotId}`,
  )
}

export function restoreInstanceSnapshot(instanceId: number, snapshotId: number | string) {
  return client.post<ApiResponse<InstanceSnapshotRestoreResult>>(
    `/v1/instances/${instanceId}/snapshots/${snapshotId}/restore`,
  )
}

export function listInstanceCronSnapshots(instanceId: number) {
  return client.get<ApiResponse<InstanceCronSnapshotItem[] | InstanceCronSnapshotList>>(
    `/v1/instances/${instanceId}/cron-snapshots`,
  )
}

export function createInstanceCronSnapshot(instanceId: number, payload: InstanceCronSnapshotCreatePayload) {
  return client.post<ApiResponse<Record<string, unknown>>>(
    `/v1/instances/${instanceId}/cron-snapshots`,
    payload,
  )
}

export function deleteInstanceCronSnapshot(instanceId: number, cronId: number | string) {
  return client.delete<ApiResponse<Record<string, unknown>>>(
    `/v1/instances/${instanceId}/cron-snapshots/${cronId}`,
  )
}

export interface UpstreamTask {
  id: number
  type: string
  status: number       // 0未开始 1正在执行 2成功 3失败 4强制结束 5取消
  create_time: string
  start_time: string
  end_time: string
  progress: number
  msg: string
  hostid: number
  hostname: string
  rel_type: string
}

export function listTasks(instanceId: number) {
  return client.get<ApiResponse<{ list: UpstreamTask[]; meta: { total?: number } }>>(
    `/v1/instances/${instanceId}/tasks`,
    { params: { page: 1, per_page: 5 } },
  )
}

export interface FinanceFirewallItem {
  id?: number | string | null
  name?: string | null
  description?: string | null
  direction?: string | null
  protocol?: string | null
  port?: string | number | null
  ip?: string | null
  source?: string | null
  status?: string | number | null
  create_time?: string | null
  [key: string]: unknown
}

export interface FinanceFirewallResult {
  supported?: boolean
  message?: string
  list: FinanceFirewallItem[]
}

export function getFinanceFirewall(instanceId: number) {
  return client.get<ApiResponse<FinanceFirewallResult>>(`/v1/instances/${instanceId}/finance-firewall`)
}

export interface VncInfo {
  token: string | null
  vnc_pass: string | null
  vnc_url: string | null
  vnc_url_http: string | null
  vnc_url_https: string | null
  password: string | null
  path: number | string | null
  direct_url?: string | null
  provider?: string | null
}

export function openVnc(instanceId: number) {
  return client.post<ApiResponse<VncInfo>>(`/v1/instances/${instanceId}/vnc`)
}

export interface VncTicket {
  ticket: string
  expires_in: number
  vnc_pass: string | null
  password: string | null
  hostname: string | null
  instance_id: number
  direct_url?: string | null
  provider?: string | null
  connection_type?: "websocket" | "direct_url" | string | null
}

export function issueVncTicket(instanceId: number) {
  return client.post<ApiResponse<VncTicket>>(`/v1/instances/${instanceId}/vnc-ticket`)
}

// 配置升级相关接口
export interface UpgradeProduct {
  id: number
  name: string
  description: string | null
  cycle: string
  cycle_price: number
  monthly_price?: number
  cpu: number | null
  memory: number | null
  bandwidth: number | null
  in_bw: number | null
  out_bw: number | null
  traffic_quota?: number | null
  traffic_type?: number | null
  nat_acl_limit?: number | null
  nat_web_limit?: number | null
  memory_display: string | null
  disk_display: string | null
  bandwidth_display: string | null
}

export interface UpgradeQuotePayload {
  target_product_id: number
}

export interface UpgradeQuoteResult {
  current_product: {
    id: number
    name: string
    cycle: string
    cycle_price: number
    monthly_price?: number
    cpu: number | null
    memory: number | null
    bandwidth: number | null
    in_bw: number | null
    out_bw: number | null
  }
  target_product: {
    id: number
    name: string
    cycle: string
    cycle_price: number
    monthly_price?: number
    cpu: number | null
    memory: number | null
    bandwidth: number | null
    in_bw: number | null
    out_bw: number | null
  }
  is_upgrade: boolean
  is_downgrade: boolean
  price_diff_cents: number
  price_diff_yuan: number
  current_charge: number
  remaining_days: number
  remaining_seconds: number
  new_unit_price: number
  new_renew_amount: number
  disk_addon_amount: number
}

export interface UpgradeExecutePayload {
  target_product_id: number
}

export interface UpgradeExecuteResult {
  instance_id: number
  charged: number
  balance?: number
  order_id?: number | null
  order_no?: string | null
  new_unit_price: number
  new_renew_amount: number
  is_downgrade: boolean
}

export function getUpgradeProducts(instanceId: number) {
  return client.get<ApiResponse<UpgradeProduct[]>>(`/v1/instances/${instanceId}/upgrade/products`)
}

export function getUpgradeQuote(instanceId: number, payload: UpgradeQuotePayload) {
  return client.post<ApiResponse<UpgradeQuoteResult>>(`/v1/instances/${instanceId}/upgrade/quote`, payload)
}

export function executeUpgrade(instanceId: number, payload: UpgradeExecutePayload) {
  return client.post<ApiResponse<UpgradeExecuteResult>>(`/v1/instances/${instanceId}/upgrade`, payload)
}
