import adminClient from "./client"
import type { ApiResponse } from "../../types"
import type { BusinessSettingValue, FeaturePlugin } from "./settings"
import { listResult } from "./response"

export interface NotificationPlugin extends FeaturePlugin {
  current: boolean
  enabled: boolean
  protected?: boolean
  runtime?: string
  config_schema?: {
    fields?: FeaturePlugin["config_fields"]
  }
  requirements?: {
    python_packages?: string[]
    network?: string[]
  }
}

export interface PluginConfigPayload {
  plugin: NotificationPlugin
  values: Record<string, BusinessSettingValue>
}

export interface PluginTestPayload {
  target?: string
  mode?: "two_factor" | "three_factor" | "face_redirect" | string
  real_name?: string
  id_card_no?: string
  phone?: string
  return_url?: string
  values: Record<string, BusinessSettingValue>
}

export interface PluginTestResult {
  sent?: boolean
  mode?: string
  passed?: boolean
  status?: string
  reason?: string
  external_id?: string | null
  url?: string
  expires_in?: number | null
  raw?: unknown
}

const BASE = "/v1/admin/settings/notification-plugins"

export type PluginType = "email" | "sms" | "verification" | "payment" | "auth"

export async function listNotificationPlugins(pluginType?: PluginType) {
  const { data } = await adminClient.get<ApiResponse<NotificationPlugin[] | { items: NotificationPlugin[] }>>(BASE, {
    params: pluginType ? { plugin_type: pluginType } : undefined,
  })
  return { ...data, data: listResult<NotificationPlugin>(data.data) }
}

export async function getNotificationPluginConfig(type: string, id: string) {
  const { data } = await adminClient.get<ApiResponse<PluginConfigPayload>>(`${BASE}/${type}/${id}/config`)
  return data
}

export async function saveNotificationPluginConfig(
  type: string,
  id: string,
  values: Record<string, BusinessSettingValue>,
) {
  const { data } = await adminClient.put<ApiResponse<PluginConfigPayload>>(`${BASE}/${type}/${id}/config`, { values })
  return data
}

export async function enableNotificationPlugin(type: string, id: string) {
  const { data } = await adminClient.post<ApiResponse<{ enabled: boolean; plugin: NotificationPlugin }>>(`${BASE}/${type}/${id}/enable`)
  return data
}

export async function disableNotificationPlugin(type: string, id: string) {
  const { data } = await adminClient.post<ApiResponse<{ enabled: boolean; plugin: NotificationPlugin }>>(`${BASE}/${type}/${id}/disable`)
  return data
}

export async function testNotificationPlugin(
  type: string,
  id: string,
  payload: PluginTestPayload,
) {
  const { data } = await adminClient.post<ApiResponse<PluginTestResult>>(`${BASE}/${type}/${id}/test`, payload)
  return data
}

export async function deleteNotificationPlugin(type: string, id: string) {
  const { data } = await adminClient.delete<ApiResponse<{ deleted: boolean; plugin_id: string; type: string }>>(`${BASE}/${type}/${id}`)
  return data
}

export async function previewNotificationPlugin(file: File) {
  const form = new FormData()
  form.append("file", file)
  const { data } = await adminClient.post<ApiResponse<NotificationPlugin & { exists: boolean; install_path: string; root_dir: string }>>(`${BASE}/preview`, form, {
    headers: { "Content-Type": "multipart/form-data" },
    timeout: 60_000,
  })
  return data
}

export async function installNotificationPlugin(file: File, overwrite = false) {
  const form = new FormData()
  form.append("file", file)
  const { data } = await adminClient.post<ApiResponse<NotificationPlugin>>(`${BASE}/install`, form, {
    params: { overwrite },
    headers: { "Content-Type": "multipart/form-data" },
    timeout: 60_000,
  })
  return data
}

export async function reloadNotificationPlugins(options: { install_dependencies: boolean; restart_backend: boolean }) {
  const { data } = await adminClient.post<ApiResponse<{
    dependencies: { installed: boolean; packages: string[]; pending_packages: string[]; python: string; result: unknown }
    restart: { requested: boolean; mode: string; result: unknown }
  }>>(`${BASE}/reload`, options)
  return data
}
