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

import { showError, showSuccess } from '@/lib/feedback'
import {
  fetchAdminKuaishouCloudFulfillmentConfig,
  fetchAdminKuaishouEticketSourceConfig,
  fetchAdminCloudtentaclesSourceConfig,
  saveAdminKuaishouCloudFulfillmentConfig,
} from '@/services/admin'
import type {
  AdminKuaishouCloudFulfillmentConfig,
  AdminKuaishouCloudFulfillmentItem,
  AdminKuaishouEticketShopConfigItem,
} from '@/types/admin'
import { hasAdminRole } from '@/utils/admin-auth'

import type { EditableItem, RuleFilter, ValidationState } from './types'

export function useKuaishouCloudConfig() {
  const loading = ref(true)
  const saving = ref(false)
  const errorMessage = ref('')
  const validationState = ref<ValidationState>(null)
  const filePath = ref('')
  const enabled = ref(true)
  const items = ref<EditableItem[]>([])
  const collapsedIds = ref<string[]>([])
  const ruleFilter = ref<RuleFilter>('all')
  const kuaishouConsumeShops = ref<AdminKuaishouEticketShopConfigItem[]>([])
  const cloudtentaclesSourceOptions = ref<{ key: string; label: string }[]>([])

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

  const metrics = computed(() => {
    const readyCount = items.value.filter(isItemComplete).length
    const enabledCount = items.value.filter((item) => item.enabled).length
    const disabledCount = items.value.filter((item) => !item.enabled).length
    return {
      total: items.value.length,
      readyCount,
      enabledCount,
      disabledCount,
      draftCount: items.value.filter((item) => item.enabled && !isItemComplete(item)).length,
    }
  })

  const filteredItems = computed(() =>
    items.value.filter((item) => matchesRuleFilter(item, ruleFilter.value)),
  )

  const ruleFilterOptions = computed<Array<{ value: RuleFilter; label: string; count: number }>>(
    () => [
      { value: 'all', label: '全部', count: metrics.value.total },
      { value: 'draft', label: '待完善', count: metrics.value.draftCount },
      { value: 'ready', label: '可投产', count: metrics.value.readyCount },
      { value: 'disabled', label: '已停用', count: metrics.value.disabledCount },
    ],
  )

  // ── item factories ───────────────────────────────────

  function createEmptyItem(): EditableItem {
    const defaultShop = getDefaultKuaishouConsumeShop()
    return {
      localId: crypto.randomUUID(),
      id: '',
      enabled: true,
      priority: 100,
      provider: '91kaquan',
      platform: 'kuaishou',
      shopId: '',
      internalSkuCode: '',
      internalSkuName: '',
      externalSkuCode: '',
      externalItemId: '',
      externalSkuName: '',
      resolvedSkuName: '',
      cloudSourceKey: 'default',
      cloudSkuId: 0,
      cloudSkuName: '',
      vnKey: '1',
      autoBuyEnabled: true,
      minAssetReserve: 0,
      autoReturnNumberAfterDispatch: false,
      autoConsumeAfterDispatch: false,
      kuaishouConsumeShopId: defaultShop?.shopId || '',
      kuaishouConsumeShopName: defaultShop?.kshopName || '',
      notes: '',
      cloudSourceKeyFallbacks: [],
    }
  }

  function mapEditableItem(item: AdminKuaishouCloudFulfillmentItem): EditableItem {
    const matchedShop = findKuaishouConsumeShop(
      item.kuaishouConsumeShopId,
      item.kuaishouConsumeShopName,
    )
    return {
      localId: crypto.randomUUID(),
      id: item.id || crypto.randomUUID(),
      enabled: item.enabled !== false,
      priority: item.priority || 100,
      provider: item.provider || '91kaquan',
      platform: item.platform || 'kuaishou',
      shopId: item.shopId || '',
      internalSkuCode: item.internalSkuCode || '',
      internalSkuName: item.internalSkuName || '',
      externalSkuCode: item.externalSkuCode || '',
      externalItemId: item.externalItemId || '',
      externalSkuName: item.externalSkuName || '',
      resolvedSkuName: item.resolvedSkuName || '',
      cloudSourceKey: item.cloudSourceKey || 'default',
      cloudSkuId: Number(item.cloudSkuId || 0) || 0,
      cloudSkuName: item.cloudSkuName || '',
      vnKey: item.vnKey || '',
      autoBuyEnabled: item.autoBuyEnabled !== false,
      minAssetReserve: Number(item.minAssetReserve || 0) || 0,
      autoReturnNumberAfterDispatch: item.autoReturnNumberAfterDispatch === true,
      autoConsumeAfterDispatch: item.autoConsumeAfterDispatch === true,
      kuaishouConsumeShopId: matchedShop?.shopId || item.kuaishouConsumeShopId || '',
      kuaishouConsumeShopName: matchedShop?.kshopName || item.kuaishouConsumeShopName || '',
      notes: item.notes || '',
      cloudSourceKeyFallbacks: Array.isArray(item.cloudSourceKeyFallbacks)
        ? item.cloudSourceKeyFallbacks
        : [],
    }
  }

  function mapSaveItem(item: EditableItem): AdminKuaishouCloudFulfillmentItem {
    const matchedShop = findKuaishouConsumeShop(
      item.kuaishouConsumeShopId,
      item.kuaishouConsumeShopName,
    )
    return {
      id: item.id.trim() || item.internalSkuCode.trim() || item.localId,
      enabled: item.enabled,
      priority: Number(item.priority || 100) || 100,
      provider: item.provider.trim() || '91kaquan',
      platform: item.platform.trim() || 'kuaishou',
      shopId: item.shopId.trim(),
      internalSkuCode: item.internalSkuCode.trim(),
      internalSkuName: item.internalSkuName.trim(),
      externalSkuCode: item.externalSkuCode.trim(),
      externalItemId: item.externalItemId.trim(),
      externalSkuName: item.externalSkuName.trim(),
      resolvedSkuName: item.resolvedSkuName.trim(),
      cloudSourceKey: item.cloudSourceKey.trim() || 'default',
      cloudSkuId: Number(item.cloudSkuId || 0) || 0,
      cloudSkuName: item.cloudSkuName.trim(),
      vnKey: item.vnKey.trim(),
      autoBuyEnabled: item.autoBuyEnabled,
      minAssetReserve: Math.max(0, Number(item.minAssetReserve || 0) || 0),
      autoReturnNumberAfterDispatch: item.autoReturnNumberAfterDispatch,
      autoConsumeAfterDispatch: item.autoConsumeAfterDispatch,
      kuaishouConsumeShopId: String(matchedShop?.shopId || item.kuaishouConsumeShopId).trim(),
      kuaishouConsumeShopName: String(
        matchedShop?.kshopName || item.kuaishouConsumeShopName,
      ).trim(),
      notes: item.notes.trim(),
      cloudSourceKeyFallbacks: Array.isArray(item.cloudSourceKeyFallbacks)
        ? item.cloudSourceKeyFallbacks.filter(Boolean)
        : [],
    }
  }

  // ── validation helpers ────────────────────────────────

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

  function hasMeaningfulContent(item: EditableItem) {
    return Boolean(
      item.internalSkuCode.trim() ||
        item.internalSkuName.trim() ||
        item.externalSkuCode.trim() ||
        item.externalItemId.trim() ||
        item.externalSkuName.trim() ||
        item.resolvedSkuName.trim() ||
        item.cloudSourceKey.trim() !== 'default' ||
        Number(item.cloudSkuId || 0) > 0 ||
        item.cloudSkuName.trim() ||
        item.vnKey.trim() ||
        item.shopId.trim() ||
        item.notes.trim() ||
        item.provider.trim() !== '91kaquan' ||
        item.platform.trim() !== 'kuaishou' ||
        item.priority !== 100 ||
        item.autoBuyEnabled !== true ||
        item.minAssetReserve !== 0 ||
        item.autoReturnNumberAfterDispatch ||
        item.autoConsumeAfterDispatch ||
        item.kuaishouConsumeShopId.trim() ||
        item.kuaishouConsumeShopName.trim() ||
        item.enabled !== true,
    )
  }

  function isItemComplete(item: EditableItem) {
    return Boolean(
      item.internalSkuCode.trim() &&
        Number(item.cloudSkuId || 0) > 0 &&
        (!item.autoConsumeAfterDispatch || Boolean(item.kuaishouConsumeShopId.trim())) &&
        hasExternalMatch(item),
    )
  }

  function resolveValidation(item: EditableItem, index: number): ValidationState {
    if (!hasMeaningfulContent(item)) {
      return null
    }

    const title = `第 ${index + 1} 条规则`

    if (!item.internalSkuCode.trim()) {
      return { localId: item.localId, message: `${title} 缺少内部 SKU 编码` }
    }

    if (Number(item.cloudSkuId || 0) <= 0) {
      return { localId: item.localId, message: `${title} 需要填写 cloud SKU ID` }
    }

    if (!hasExternalMatch(item)) {
      return { localId: item.localId, message: `${title} 至少填写一种外部匹配条件` }
    }

    if (item.autoConsumeAfterDispatch && !item.kuaishouConsumeShopId.trim()) {
      return { localId: item.localId, message: `${title} 已开启发货后核销，需要选择快手核销店铺` }
    }

    return null
  }

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

  function getCardTitle(item: EditableItem, index: number) {
    return (
      item.internalSkuName.trim() ||
      item.externalSkuName.trim() ||
      item.internalSkuCode.trim() ||
      `规则 ${index + 1}`
    )
  }

  function getCardSummary(item: EditableItem) {
    const parts = [
      item.provider.trim() || '91kaquan',
      item.platform.trim() || 'kuaishou',
      item.shopId.trim() || '跨店铺',
      item.cloudSkuId > 0 ? `cloud#${item.cloudSkuId}` : '待填 cloud SKU',
    ]
    return parts.join(' / ')
  }

  function getRuleState(item: EditableItem) {
    if (!item.enabled) {
      return { label: '已停用', tone: 'muted' }
    }

    if (isItemComplete(item)) {
      return { label: '可投产', tone: 'success' }
    }

    return { label: '草稿待完善', tone: 'warning' }
  }

  function matchesRuleFilter(item: EditableItem, filter: RuleFilter) {
    if (filter === 'ready') {
      return item.enabled && isItemComplete(item)
    }

    if (filter === 'draft') {
      return item.enabled && !isItemComplete(item)
    }

    if (filter === 'disabled') {
      return !item.enabled
    }

    return true
  }

  function getExternalMatchSummary(item: EditableItem) {
    const parts = [
      item.externalSkuCode.trim() ? `SKU ${item.externalSkuCode.trim()}` : '',
      item.externalItemId.trim() ? `Item ${item.externalItemId.trim()}` : '',
      item.externalSkuName.trim() ? item.externalSkuName.trim() : '',
    ].filter(Boolean)

    return parts.length > 0 ? parts.join(' / ') : '未设置外部命中条件'
  }

  // ── kuaishou consume shop helpers ─────────────────────

  function getKuaishouConsumeShopOptions() {
    return kuaishouConsumeShops.value.filter((shop) => shop.enabled !== false && shop.hasCookie)
  }

  function findKuaishouConsumeShop(shopId = '', shopName = '') {
    const normalizedShopId = String(shopId || '').trim()
    const normalizedShopName = String(shopName || '').trim()
    return (
      getKuaishouConsumeShopOptions().find(
        (shop) =>
          (normalizedShopId && shop.shopId === normalizedShopId) ||
          (normalizedShopName && shop.kshopName === normalizedShopName),
      ) || null
    )
  }

  function getDefaultKuaishouConsumeShop() {
    return getKuaishouConsumeShopOptions()[0] || null
  }

  function formatKuaishouConsumeShopOption(shop: AdminKuaishouEticketShopConfigItem) {
    return `${shop.kshopName || '未命名快手小店'} · ${shop.shopId}`
  }

  function handleKuaishouConsumeShopSelected(item: EditableItem) {
    const matchedShop = findKuaishouConsumeShop(item.kuaishouConsumeShopId)
    item.kuaishouConsumeShopName = matchedShop?.kshopName || ''
  }

  function getConsumeShopSummary(item: EditableItem) {
    const matchedShop = findKuaishouConsumeShop(
      item.kuaishouConsumeShopId,
      item.kuaishouConsumeShopName,
    )
    const name = String(matchedShop?.kshopName || item.kuaishouConsumeShopName).trim()
    const id = String(matchedShop?.shopId || item.kuaishouConsumeShopId).trim()

    if (name && id) {
      return `${name} · ${id}`
    }

    return name || id || '未绑定核销店铺'
  }

  function getCloudSkuSummary(item: EditableItem) {
    if (item.cloudSkuId > 0 && item.cloudSkuName.trim()) {
      return `${item.cloudSkuName.trim()} · #${item.cloudSkuId}`
    }

    if (item.cloudSkuId > 0) {
      return `cloud SKU #${item.cloudSkuId}`
    }

    return '待选择 cloud SKU'
  }

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

  function isCollapsed(localId: string) {
    return collapsedIds.value.includes(localId)
  }

  function setCollapsed(localId: string, collapsed: boolean) {
    const next = new Set(collapsedIds.value)
    if (collapsed) {
      next.add(localId)
    } else {
      next.delete(localId)
    }
    collapsedIds.value = Array.from(next)
  }

  function toggleCollapsed(localId: string) {
    setCollapsed(localId, !isCollapsed(localId))
  }

  function rebuildCollapsedState() {
    collapsedIds.value = items.value.filter(isItemComplete).map((item) => item.localId)
  }

  function expandAllRules() {
    collapsedIds.value = []
  }

  function collapseReadyRules() {
    collapsedIds.value = items.value
      .filter((item) => isItemComplete(item) || !item.enabled)
      .map((item) => item.localId)
  }

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

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

    loading.value = true
    errorMessage.value = ''

    try {
      const [response, eticketResponse, cloudtentaclesSourceResponse] = await Promise.all([
        fetchAdminKuaishouCloudFulfillmentConfig(),
        fetchAdminKuaishouEticketSourceConfig(),
        fetchAdminCloudtentaclesSourceConfig(),
      ])
      kuaishouConsumeShops.value = Array.isArray(eticketResponse.data.source.shops)
        ? eticketResponse.data.source.shops
        : []
      const sources = Array.isArray(cloudtentaclesSourceResponse.data.sources)
        ? cloudtentaclesSourceResponse.data.sources
        : []
      cloudtentaclesSourceOptions.value = sources.map((s) => ({
        key: s.key,
        label: s.label || s.key,
      }))
      filePath.value = response.data.filePath
      enabled.value = response.data.source.enabled !== false
      items.value = (response.data.source.items || []).map(mapEditableItem)
      rebuildCollapsedState()
    } catch (error) {
      errorMessage.value = error instanceof Error ? error.message : '读取新履约配置失败'
    } finally {
      loading.value = false
    }
  }

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

  function addItem() {
    validationState.value = null
    const next = createEmptyItem()
    items.value.unshift(next)
    setCollapsed(next.localId, false)
  }

  function removeItem(localId: string) {
    if (validationState.value?.localId === localId) {
      validationState.value = null
    }
    items.value = items.value.filter((item) => item.localId !== localId)
    setCollapsed(localId, false)
  }

  async function focusValidationTarget(localId: string) {
    if (!localId) {
      return
    }

    await nextTick()
    const card = document.querySelector<HTMLElement>(`[data-local-id="${localId}"]`)
    if (!card) {
      return
    }

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

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

  async function saveConfigs() {
    const invalid = items.value.reduce<ValidationState>(
      (state, item, index) => state || resolveValidation(item, index),
      null,
    )
    if (invalid) {
      validationState.value = invalid
      setCollapsed(invalid.localId, false)
      showError(invalid.message)
      await focusValidationTarget(invalid.localId)
      return
    }

    const payloadItems = items.value.filter(hasMeaningfulContent).map(mapSaveItem)
    const payload: AdminKuaishouCloudFulfillmentConfig = {
      enabled: enabled.value,
      items: payloadItems,
    }

    saving.value = true
    validationState.value = null

    try {
      const response = await saveAdminKuaishouCloudFulfillmentConfig(payload)
      filePath.value = response.data.filePath
      enabled.value = response.data.source.enabled !== false
      items.value = (response.data.source.items || []).map(mapEditableItem)
      rebuildCollapsedState()
      showSuccess('新履约配置已保存')
    } catch (error) {
      const message = error instanceof Error ? error.message : '保存新履约配置失败'
      validationState.value = { localId: '', message }
      showError(message)
    } finally {
      saving.value = false
    }
  }

  return {
    // state
    loading,
    saving,
    errorMessage,
    validationState,
    filePath,
    enabled,
    items,
    collapsedIds,
    ruleFilter,
    kuaishouConsumeShops,
    // computed
    metrics,
    filteredItems,
    ruleFilterOptions,
    // factories
    createEmptyItem,
    mapEditableItem,
    // validation
    isItemComplete,
    resolveValidation,
    hasMeaningfulContent,
    // display
    getCardTitle,
    getCardSummary,
    getRuleState,
    getExternalMatchSummary,
    getCloudSkuSummary,
    getConsumeShopSummary,
    // consume shops
    getKuaishouConsumeShopOptions,
    findKuaishouConsumeShop,
    getDefaultKuaishouConsumeShop,
    formatKuaishouConsumeShopOption,
    handleKuaishouConsumeShopSelected,
    // collapse
    isCollapsed,
    setCollapsed,
    toggleCollapsed,
    expandAllRules,
    collapseReadyRules,
    // data
    loadConfigs,
    addItem,
    removeItem,
    saveConfigs,
    focusValidationTarget,
    // cloudtentacles sources
    cloudtentaclesSourceOptions,
  }
}
