import { ref, computed } from 'vue'
import { http } from '@/api'
import type { usePushForm } from './usePushForm'
import type { usePushServers } from './usePushServers'
import {
  PREVIEW_CONCURRENCY,
  PREVIEW_WARN_THRESHOLD,
  type PreviewServerRow,
  type PreviewStats,
} from './types'

type PushForm = ReturnType<typeof usePushForm>
type PushServers = ReturnType<typeof usePushServers>

export function usePushPreview(form: PushForm, servers: PushServers) {
  const showPreview = ref(false)
  const previewResults = ref<PreviewServerRow[]>([])
  const previewLoading = ref(false)
  const previewTotal = ref(0)
  const previewDone = ref(0)

  const previewLargeBatch = computed(() => previewTotal.value > PREVIEW_WARN_THRESHOLD)

  const previewErrorCount = computed(() => previewResults.value.filter(r => r.error).length)

  async function previewOneServer(serverId: number, serverName: string): Promise<PreviewServerRow> {
    try {
      const res = await http.post<{
        server_id: number
        server_name: string
        error?: string
        stats?: PreviewStats
      }>('/sync/preview', {
        source_path: form.effectiveSourcePath(),
        target_path: form.effectiveTargetPath(),
        server_id: serverId,
        sync_mode: form.syncMode.value,
      })
      if (res.error) {
        return { server_id: serverId, server_name: serverName, error: res.error }
      }
      return {
        server_id: serverId,
        server_name: res.server_name || serverName,
        stats: res.stats,
      }
    } catch (e: unknown) {
      return {
        server_id: serverId,
        server_name: serverName,
        error: e instanceof Error ? e.message : '预览失败',
      }
    }
  }

  async function doPreview() {
    const selected = [...servers.selectedIds.value]
      .map(id => servers.servers.value.find(s => s.id === id))
      .filter((s): s is NonNullable<typeof s> => s != null)
    if (!form.validateForm(selected.length, selected)) return

    const allIds = selected.map(s => s.id)
    previewTotal.value = allIds.length
    previewDone.value = 0

    showPreview.value = true
    previewLoading.value = true
    previewResults.value = []

    const queue = allIds.map(id => {
      const srv = servers.servers.value.find(s => s.id === id)
      return { id, name: srv?.name || `#${id}` }
    })

    for (let i = 0; i < queue.length; i += PREVIEW_CONCURRENCY) {
      const batch = queue.slice(i, i + PREVIEW_CONCURRENCY)
      const rows = await Promise.all(batch.map(s => previewOneServer(s.id, s.name)))
      previewResults.value = [...previewResults.value, ...rows]
      previewDone.value = previewResults.value.length
    }

    previewLoading.value = false
  }

  function closePreview() {
    showPreview.value = false
  }

  function confirmAndPush(doPush: () => void) {
    showPreview.value = false
    doPush()
  }

  return {
    showPreview,
    previewResults,
    previewLoading,
    previewTotal,
    previewDone,
    previewLargeBatch,
    previewWarnThreshold: PREVIEW_WARN_THRESHOLD,
    previewErrorCount,
    doPreview,
    closePreview,
    confirmAndPush,
  }
}
