import { computed, nextTick, ref } from 'vue'

import { showSuccess } from '@/lib/feedback'
import {
  fetchAdminFulfillmentBindingConfigs,
  saveAdminFulfillmentBindingConfigs,
} from '@/services/admin'
import type {
  AdminFulfillmentBindingConfigItem,
  AdminObservedProductItem,
} from '@/types/admin'
import { hasAdminRole } from '@/utils/admin-auth'

import {
  VALID_PROFILE_KEYS,
  type EditableBinding,
  type ImportableProductCandidate,
  type SaveBindingPayload,
  type ValidationField,
  type ValidationState,
} from './types'

export function useFulfillmentBindings() {
  const loading = ref(true)
  const saving = ref(false)
  const errorMessage = ref('')
  const filePath = ref('')
  const bindings = ref<EditableBinding[]>([])
  const observedProducts = ref<AdminObservedProductItem[]>([])
  const validationState = ref<ValidationState>(null)
  const collapsedBindingIds = ref<string[]>([])

  // ── computed ──────────────────────────────────────────

  const ruleMetrics = computed(() => {
    const completedCount = bindings.value.filter(isEditableBindingComplete).length
    const manualCount = bindings.value.filter(
      (item) => item.profileKey.trim() === 'manual_review',
    ).length
    const assistedCount = bindings.value.filter(
      (item) => item.profileKey.trim() === 'tencent_claim_assisted',
    ).length
    const kuaishouCloudCount = bindings.value.filter(
      (item) => item.profileKey.trim() === 'kuaishou_ct_assisted',
    ).length

    return {
      totalCount: bindings.value.length,
      completedCount,
      draftCount: Math.max(bindings.value.length - completedCount, 0),
      manualCount,
      assistedCount,
      kuaishouCloudCount,
    }
  })

  const pendingObservedCount = computed(
    () => observedProducts.value.filter((item) => !item.configured).length,
  )

  // ── factories ────────────────────────────────────────

  function createEmptyBinding(): EditableBinding {
    return {
      id: crypto.randomUUID(),
      provider: 'agiso',
      platform: '',
      shopId: '',
      shopName: '',
      skuCode: '',
      skuName: '',
      profileKey: 'manual_review',
      enabled: true,
      priority: 100,
      externalSkuCode: '',
      externalItemId: '',
      externalSkuName: '',
      resolvedSkuName: '',
    }
  }

  function mapEditableBinding(item: AdminFulfillmentBindingConfigItem): EditableBinding {
    return {
      id: crypto.randomUUID(),
      provider: item.provider || 'agiso',
      platform: item.platform,
      shopId: item.shopId,
      shopName: item.shopName || '',
      skuCode: item.skuCode,
      skuName: item.skuName,
      profileKey: item.profileKey || 'manual_review',
      enabled: item.enabled !== false,
      priority: item.priority || 100,
      externalSkuCode: item.match.externalSkuCode,
      externalItemId: item.match.externalItemId,
      externalSkuName: item.match.externalSkuName,
      resolvedSkuName: String(item.match.config?.resolvedSkuName || ''),
    }
  }

  // ── validation ────────────────────────────────────────

  function hasMatchCondition(
    item: Pick<EditableBinding, 'externalSkuCode' | 'externalItemId' | 'externalSkuName'>,
  ) {
    return Boolean(
      item.externalSkuCode.trim() || item.externalItemId.trim() || item.externalSkuName.trim(),
    )
  }

  function isEditableBindingComplete(item: EditableBinding) {
    return Boolean(
      item.skuCode.trim() &&
      hasMatchCondition(item) &&
      VALID_PROFILE_KEYS.has(item.profileKey.trim() || 'manual_review'),
    )
  }

  // ── collapse state ────────────────────────────────────

  function buildCollapsedIds(items: EditableBinding[]) {
    return items.filter(isEditableBindingComplete).map((item) => item.id)
  }

  function isBindingCollapsed(bindingId: string) {
    return collapsedBindingIds.value.includes(bindingId)
  }

  function setBindingCollapsed(bindingId: string, collapsed: boolean) {
    const next = new Set(collapsedBindingIds.value)

    if (collapsed) {
      next.add(bindingId)
    } else {
      next.delete(bindingId)
    }

    collapsedBindingIds.value = Array.from(next)
  }

  function toggleBindingCollapsed(bindingId: string) {
    setBindingCollapsed(bindingId, !isBindingCollapsed(bindingId))
  }

  // ── display helpers ───────────────────────────────────

  function getBindingTitle(binding: EditableBinding, index: number) {
    const internalName = binding.skuName.trim()
    const externalName = binding.externalSkuName.trim()
    const skuCode = binding.skuCode.trim()

    return internalName || externalName || skuCode || `规则 ${index + 1}`
  }

  function getBindingStatusLabel(binding: EditableBinding) {
    return isEditableBindingComplete(binding) ? '已完成' : '待完善'
  }

  function getBindingSummary(binding: EditableBinding) {
    const parts = [
      binding.provider.trim() || 'agiso',
      binding.platform.trim() || '未选平台',
      binding.shopName.trim() || binding.shopId.trim() || '跨店铺',
      binding.profileKey.trim() || 'manual_review',
    ]

    return parts.join(' / ')
  }

  // ── data loading ──────────────────────────────────────

  async function loadConfigs() {
    if (!hasAdminRole('admin')) {
      loading.value = false
      return
    }

    loading.value = true
    errorMessage.value = ''

    try {
      const response = await fetchAdminFulfillmentBindingConfigs()
      filePath.value = response.data.filePath
      const nextBindings = response.data.bindings.map(mapEditableBinding)
      bindings.value = nextBindings
      collapsedBindingIds.value = buildCollapsedIds(nextBindings)
      observedProducts.value = response.data.observedProducts
    } catch (error) {
      errorMessage.value = error instanceof Error ? error.message : '读取履约配置失败'
    } finally {
      loading.value = false
    }
  }

  // ── mutation ──────────────────────────────────────────

  function addBinding() {
    validationState.value = null
    const next = createEmptyBinding()
    setBindingCollapsed(next.id, false)
    bindings.value.unshift(next)
  }

  function removeBinding(id: string) {
    if (validationState.value?.bindingId === id) {
      validationState.value = null
    }
    setBindingCollapsed(id, false)
    bindings.value = bindings.value.filter((item) => item.id !== id)
  }

  // ── import from observed products ────────────────────

  function createBindingFromProductCandidate(item: ImportableProductCandidate): EditableBinding {
    const binding = {
      id: crypto.randomUUID(),
      provider: item.provider || 'agiso',
      platform: item.platform,
      shopId: item.shopId,
      shopName: item.shopName,
      skuCode: '',
      skuName: item.externalSkuName,
      profileKey: 'manual_review',
      enabled: true,
      priority: 100,
      externalSkuCode: item.externalSkuCode,
      externalItemId: item.externalItemId,
      externalSkuName: item.externalSkuName,
      resolvedSkuName: item.externalSkuName,
    }

    return binding
  }

  function importObservedProduct(item: ImportableProductCandidate) {
    validationState.value = null
    const nextBinding = createBindingFromProductCandidate(item)
    setBindingCollapsed(nextBinding.id, false)
    bindings.value.unshift(nextBinding)
  }

  // ── save ──────────────────────────────────────────────

  function normalizeBindingForSave(item: EditableBinding): SaveBindingPayload {
    return {
      provider: item.provider.trim() || 'agiso',
      platform: item.platform.trim(),
      shopId: item.shopId.trim(),
      shopName: item.shopName.trim(),
      skuCode: item.skuCode.trim(),
      skuName: item.skuName.trim(),
      profileKey: item.profileKey.trim() || 'manual_review',
      enabled: item.enabled,
      priority: Number(item.priority || 100),
      match: {
        externalSkuCode: item.externalSkuCode.trim(),
        externalItemId: item.externalItemId.trim(),
        externalSkuName: item.externalSkuName.trim(),
        config: {
          resolvedSkuName: item.resolvedSkuName.trim(),
        },
      },
    }
  }

  function hasBindingContent(item: SaveBindingPayload) {
    return Boolean(
      item.platform ||
      item.shopId ||
      item.shopName ||
      item.skuCode ||
      item.skuName ||
      item.match.externalSkuCode ||
      item.match.externalItemId ||
      item.match.externalSkuName ||
      item.match.config.resolvedSkuName ||
      item.provider !== 'agiso' ||
      item.profileKey !== 'manual_review' ||
      item.priority !== 100 ||
      item.enabled !== true,
    )
  }

  function resolveBindingValidationState(
    item: SaveBindingPayload,
    index: number,
    bindingId: string,
  ): ValidationState {
    const label = `第 ${index + 1} 条规则`

    if (!item.skuCode) {
      return {
        bindingId,
        field: 'skuCode',
        message: `${label} 还没填写"内部履约 SKU"`,
      }
    }

    if (!item.match.externalSkuCode && !item.match.externalItemId && !item.match.externalSkuName) {
      return {
        bindingId,
        field: 'match',
        message: `${label} 至少填写一种外部匹配条件`,
      }
    }

    if (!VALID_PROFILE_KEYS.has(item.profileKey)) {
      return {
        bindingId,
        field: 'profileKey',
        message: `${label} 的履约方式无效`,
      }
    }

    return null
  }

  async function focusValidationTarget(state: ValidationState) {
    if (!state?.bindingId) {
      return
    }

    setBindingCollapsed(state.bindingId, false)
    await nextTick()

    const card = document.querySelector<HTMLElement>(`[data-binding-id="${state.bindingId}"]`)
    if (!card) {
      return
    }

    card.scrollIntoView({ behavior: 'smooth', block: 'center' })

    const selectors: Record<ValidationField, string> = {
      shopId: '[data-field="shopId"]',
      skuCode: '[data-field="skuCode"]',
      match: '[data-field="externalSkuCode"]',
      profileKey: '[data-field="profileKey"]',
    }

    const target = card.querySelector<HTMLInputElement | HTMLSelectElement>(selectors[state.field])
    target?.focus()
  }

  function clearValidationState() {
    validationState.value = null
  }

  function isBindingInvalid(bindingId: string) {
    return validationState.value?.bindingId === bindingId
  }

  function isFieldInvalid(
    bindingId: string,
    field: ValidationField | 'externalSkuCode' | 'externalItemId' | 'externalSkuName',
  ) {
    if (validationState.value?.bindingId !== bindingId) {
      return false
    }

    if (validationState.value.field === 'match') {
      return ['externalSkuCode', 'externalItemId', 'externalSkuName'].includes(field)
    }

    return validationState.value.field === field
  }

  async function saveConfigs() {
    const normalizedBindings = bindings.value.map(normalizeBindingForSave)
    const nonEmptyBindings = normalizedBindings.filter(hasBindingContent)
    const invalidState = normalizedBindings.reduce<ValidationState>((state, item, index) => {
      if (state || !hasBindingContent(item)) {
        return state
      }

      return resolveBindingValidationState(item, index, bindings.value[index]?.id || '')
    }, null)

    if (invalidState) {
      validationState.value = invalidState
      await focusValidationTarget(invalidState)
      return
    }

    if (bindings.value.length > 0 && nonEmptyBindings.length === 0) {
      validationState.value = {
        bindingId: '',
        field: 'skuCode',
        message: '当前没有可保存的规则，请至少填写内部履约 SKU 和外部匹配条件',
      }
      return
    }

    const payload = nonEmptyBindings

    saving.value = true
    validationState.value = null

    try {
      const response = await saveAdminFulfillmentBindingConfigs({ bindings: payload })
      filePath.value = response.data.filePath
      bindings.value = response.data.bindings.map(mapEditableBinding)
      showSuccess('履约配置已保存')
      await loadConfigs()
    } catch (error) {
      validationState.value = {
        bindingId: '',
        field: 'skuCode',
        message: error instanceof Error ? error.message : '保存履约配置失败',
      }
    } finally {
      saving.value = false
    }
  }

  return {
    // state
    loading,
    saving,
    errorMessage,
    filePath,
    bindings,
    observedProducts,
    validationState,
    collapsedBindingIds,
    // computed
    ruleMetrics,
    pendingObservedCount,
    // factories
    createEmptyBinding,
    mapEditableBinding,
    // validation
    isEditableBindingComplete,
    clearValidationState,
    isBindingInvalid,
    isFieldInvalid,
    // collapse
    isBindingCollapsed,
    setBindingCollapsed,
    toggleBindingCollapsed,
    // display
    getBindingTitle,
    getBindingStatusLabel,
    getBindingSummary,
    // data
    loadConfigs,
    addBinding,
    removeBinding,
    importObservedProduct,
    createBindingFromProductCandidate,
    normalizeBindingForSave,
    saveConfigs,
  }
}
