import { useCallback } from "react"
import type { AppConfig, DesktopApi, SaveConfigInput, WorkspaceSummary } from "@qjclaw/shared-types"

interface UseSaveSettingsOptions {
  config: AppConfig | null
  desktopApi: DesktopApi
  saving: boolean
  drafts: {
    lobsterKey: string
    workspacePath: string
    imageModelApiKey: string
    videoModelApiKey: string
    copywritingModelApiKey: string
    digitalHumanVolcAccessKey: string
    digitalHumanVolcSecretKey: string
    digitalHumanQiniuAccessKey: string
    digitalHumanQiniuSecretKey: string
    videoAnalyzerBaseUrl: string
    videoAnalyzerModelId: string
    videoAnalyzerApiKey: string
    replicationBriefBaseUrl: string
    replicationBriefModelId: string
    replicationBriefApiKey: string
    vectcutBaseUrl: string
    vectcutFileBaseUrl: string
    vectcutApiKey: string
    xhsFeishuAppId: string
    xhsFeishuAppSecret: string
    xhsFeishuAppToken: string
    xhsFeishuTableId: string
  }
  setters: {
    setConfig(config: AppConfig): void
    setSaving(saving: boolean): void
    setErrorText(value: string): void
    setInfoText(value: string): void
    setWorkspacePathDraft(value: string): void
    setLobsterKeyDraft(value: string): void
    setImageModelApiKeyDraft(value: string): void
    setVideoModelApiKeyDraft(value: string): void
    setCopywritingModelApiKeyDraft(value: string): void
    setDigitalHumanVolcAccessKeyDraft(value: string): void
    setDigitalHumanVolcSecretKeyDraft(value: string): void
    setDigitalHumanQiniuAccessKeyDraft(value: string): void
    setDigitalHumanQiniuSecretKeyDraft(value: string): void
    setVideoAnalyzerApiKeyDraft(value: string): void
    setReplicationBriefApiKeyDraft(value: string): void
    setVectcutApiKeyDraft(value: string): void
    setXhsFeishuAppIdDraft(value: string): void
    setXhsFeishuAppSecretDraft(value: string): void
    setXhsFeishuAppTokenDraft(value: string): void
    setXhsFeishuTableIdDraft(value: string): void
  }
  labels: {
    saveSuccessPending: string
    saveSuccessApplied: string
    workspaceSaved: string
  }
  refresh(clearError?: boolean): Promise<WorkspaceSummary | null>
  normalizeError(value: unknown): string
}

export function useSaveSettings({
  config,
  desktopApi,
  saving,
  drafts,
  setters,
  labels,
  refresh,
  normalizeError
}: UseSaveSettingsOptions) {
  const saveConfig = useCallback(async (options?: {
    lobsterKey?: string
    workspacePath?: string
    expertModelConfig?: SaveConfigInput["expertModelConfig"]
    douyinRuntimeConfig?: SaveConfigInput["douyinRuntimeConfig"]
    xhsFeishuConfig?: SaveConfigInput["xhsFeishuConfig"]
    successMessage?: string
  }) => {
    if (!config) {
      return
    }

    const trimmedLobsterKey = options?.lobsterKey?.trim() ?? drafts.lobsterKey.trim()
    const resolvedWorkspacePath = options?.workspacePath?.trim() || drafts.workspacePath.trim() || config.workspacePath
    const resolvedExpertModelConfig = options?.expertModelConfig ?? {
      image: {
        apiKey: drafts.imageModelApiKey.trim() || undefined
      },
      video: {
        apiKey: drafts.videoModelApiKey.trim() || undefined
      },
      copywriting: {
        apiKey: drafts.copywritingModelApiKey.trim() || undefined
      },
      digitalHuman: {
        volcAccessKey: drafts.digitalHumanVolcAccessKey.trim() || undefined,
        volcSecretKey: drafts.digitalHumanVolcSecretKey.trim() || undefined,
        qiniuAccessKey: drafts.digitalHumanQiniuAccessKey.trim() || undefined,
        qiniuSecretKey: drafts.digitalHumanQiniuSecretKey.trim() || undefined
      }
    }
    const resolvedDouyinRuntimeConfig = options?.douyinRuntimeConfig ?? {
      videoAnalyzer: {
        baseUrl: drafts.videoAnalyzerBaseUrl.trim() || undefined,
        modelId: drafts.videoAnalyzerModelId.trim() || undefined,
        apiKey: drafts.videoAnalyzerApiKey.trim() || undefined
      },
      replicationBrief: {
        baseUrl: drafts.replicationBriefBaseUrl.trim() || undefined,
        modelId: drafts.replicationBriefModelId.trim() || undefined,
        apiKey: drafts.replicationBriefApiKey.trim() || undefined
      },
      vectcut: {
        baseUrl: drafts.vectcutBaseUrl.trim() || undefined,
        fileBaseUrl: drafts.vectcutFileBaseUrl.trim() || undefined,
        apiKey: drafts.vectcutApiKey.trim() || undefined
      }
    }
    const resolvedXhsFeishuConfig = options?.xhsFeishuConfig ?? {
      appId: drafts.xhsFeishuAppId.trim() || undefined,
      appSecret: drafts.xhsFeishuAppSecret.trim() || undefined,
      appToken: drafts.xhsFeishuAppToken.trim() || undefined,
      tableId: drafts.xhsFeishuTableId.trim() || undefined
    }
    const input: SaveConfigInput = {
      setupMode: config.setupMode,
      provider: config.provider,
      baseUrl: config.baseUrl,
      defaultModel: config.defaultModel,
      workspacePath: resolvedWorkspacePath,
      gatewayUrl: config.gatewayUrl,
      cloudApiBaseUrl: config.cloudApiBaseUrl,
      runtimeCloudApiBaseUrl: config.runtimeCloudApiBaseUrl.trim(),
      runtimeMode: "bundled-runtime",
      expertModelConfig: resolvedExpertModelConfig,
      douyinRuntimeConfig: resolvedDouyinRuntimeConfig,
      xhsFeishuConfig: resolvedXhsFeishuConfig,
      ...(trimmedLobsterKey ? { apiKey: trimmedLobsterKey } : {})
    }

    setters.setSaving(true)
    setters.setErrorText("")
    setters.setInfoText("")

    try {
      const savedConfig = await desktopApi.config.save(input)
      setters.setConfig(savedConfig)
      setters.setWorkspacePathDraft(savedConfig.workspacePath)
      setters.setLobsterKeyDraft("")
      setters.setImageModelApiKeyDraft("")
      setters.setVideoModelApiKeyDraft("")
      setters.setCopywritingModelApiKeyDraft("")
      setters.setDigitalHumanVolcAccessKeyDraft("")
      setters.setDigitalHumanVolcSecretKeyDraft("")
      setters.setDigitalHumanQiniuAccessKeyDraft("")
      setters.setDigitalHumanQiniuSecretKeyDraft("")
      setters.setVideoAnalyzerApiKeyDraft("")
      setters.setReplicationBriefApiKeyDraft("")
      setters.setVectcutApiKeyDraft("")
      setters.setXhsFeishuAppIdDraft("")
      setters.setXhsFeishuAppSecretDraft("")
      setters.setXhsFeishuAppTokenDraft("")
      setters.setXhsFeishuTableIdDraft("")
      setters.setInfoText(options?.successMessage ?? (trimmedLobsterKey ? labels.saveSuccessPending : labels.saveSuccessApplied))
      void refresh(false)
    } catch (error) {
      setters.setErrorText(normalizeError(error))
    } finally {
      setters.setSaving(false)
    }
  }, [config, desktopApi, drafts, labels.saveSuccessApplied, labels.saveSuccessPending, normalizeError, refresh, setters])

  const pickWorkspaceDirectory = useCallback(async () => {
    if (!config || saving) {
      return
    }

    setters.setErrorText("")
    try {
      const nextPath = await desktopApi.config.pickWorkspaceDirectory(drafts.workspacePath.trim() || config.workspacePath)
      if (!nextPath?.trim()) {
        return
      }

      setters.setWorkspacePathDraft(nextPath.trim())
      setters.setInfoText("")
    } catch (error) {
      setters.setErrorText(normalizeError(error))
    }
  }, [config, desktopApi, drafts.workspacePath, normalizeError, saving, setters])

  const restoreWorkspaceDirectory = useCallback(() => {
    if (!config) {
      return
    }

    setters.setWorkspacePathDraft(config.workspacePath)
    setters.setErrorText("")
    setters.setInfoText("")
  }, [config, setters])

  const saveWorkspaceDirectory = useCallback(async () => {
    await saveConfig({
      workspacePath: drafts.workspacePath,
      successMessage: labels.workspaceSaved
    })
  }, [drafts.workspacePath, labels.workspaceSaved, saveConfig])

  return {
    saveConfig,
    saveWorkspaceDirectory,
    restoreWorkspaceDirectory,
    pickWorkspaceDirectory
  }
}
