import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { get, postForm } from '@/utils/request'

// ── 链上充值（coin_network_config 按库查询）────────────────

export interface RechargeParentCoin {
  name: string
  nameCn: string
  unit: string
  status: number
  canRecharge: number
  sort: number
}

export interface RechargeNetworkItem {
  id: number
  name: string
  protocol: string
  status?: number
  sort: number
}

/** 某主网下 coin_network_config 一行（创建订单用） */
export interface RechargeConfigOption {
  networkConfigId: number
  coinName: string
  coinNameCn: string
  networkId: number
  networkName: string
  protocol: string
  contractAddress: string
  rechargeAddress: string
  sort: number
}

/** 与 RechargeConfigOption 对齐，供钱包/EVM 工具使用 */
export interface RechargeFlatNetworkOption {
  coinName: string
  coinNameCn: string
  networkConfigId: number
  networkId: number
  networkName: string
  protocol: string
  contractAddress: string
  rechargeAddress: string
  sort: number
}

export interface RechargeOrderDetail {
  id: number
  orderNo: string
  memberId?: number
  coinName: string
  networkConfigId?: number
  networkName: string
  rechargeAddress: string
  amount: string
  txHash: string | null
  status: number
  remark?: string | null
  createTime: string
  submitHashTime?: string | null
  updateTime?: string | null
}

export interface RechargeOrderListItem {
  id: string
  orderNo: string
  coinName: string
  networkName: string
  rechargeAddress: string
  amount: string
  txHash: string | null
  status: number
  createTime: string
  submitHashTime: string | null
  updateTime: string
}

type NetworkRef = { id?: unknown; name?: unknown; protocol?: unknown }

function mapConfigOption(row: Record<string, unknown>): RechargeConfigOption {
  const network = row.network as NetworkRef | undefined
  return {
    networkConfigId: Number(row.networkConfigId ?? row.id ?? 0),
    coinName: String(row.coinName ?? ''),
    coinNameCn: String(row.coinNameCn ?? ''),
    networkId: Number(row.networkId ?? network?.id ?? 0),
    networkName: String(row.networkName ?? network?.name ?? ''),
    protocol: String(row.protocol ?? network?.protocol ?? ''),
    contractAddress: String(row.contractAddress ?? ''),
    rechargeAddress: String(row.rechargeAddress ?? ''),
    sort: Number(row.sort ?? 0),
  }
}

function mapNetworkItem(row: Record<string, unknown>): RechargeNetworkItem {
  return {
    id: Number(row.id ?? 0),
    name: String(row.name ?? ''),
    protocol: String(row.protocol ?? ''),
    status: row.status != null ? Number(row.status) : undefined,
    sort: Number(row.sort ?? 0),
  }
}

function toFlatOption(cfg: RechargeConfigOption): RechargeFlatNetworkOption {
  return { ...cfg }
}

function mapListItem(row: Record<string, unknown>): RechargeOrderListItem {
  return {
    id: String(row.id ?? row.orderNo ?? ''),
    orderNo: String(row.orderNo ?? ''),
    coinName: String(row.coinName ?? ''),
    networkName: String(row.networkName ?? ''),
    rechargeAddress: String(row.rechargeAddress ?? ''),
    amount: String(row.amount ?? '0'),
    txHash: row.txHash != null && String(row.txHash) !== '' ? String(row.txHash) : null,
    status: Number(row.status ?? 0),
    createTime: String(row.createTime ?? ''),
    submitHashTime: row.submitHashTime != null && String(row.submitHashTime) !== '' ? String(row.submitHashTime) : null,
    updateTime: String(row.updateTime ?? ''),
  }
}

export const useDepositStore = defineStore('deposit', () => {
  const parentCoins = ref<RechargeParentCoin[]>([])
  const networkOptions = ref<RechargeNetworkItem[]>([])
  const subCoinOptions = ref<RechargeConfigOption[]>([])
  const selectedParentIndex = ref(0)
  const selectedNetworkId = ref(0)
  const selectedSubCoinIndex = ref(0)

  const loadingParents = ref(false)
  const childrenLoading = ref(false)
  const subCoinsLoading = ref(false)
  const error = ref<string | null>(null)

  const currentOrder = ref<RechargeOrderDetail | null>(null)
  const orderSubmitting = ref(false)
  const hashSubmitting = ref(false)

  const records = ref<RechargeOrderListItem[]>([])
  const lastRecordPageFetched = ref(0)
  const recordPageSize = 15
  const recordTotalPages = ref(0)
  const recordTotalElements = ref(0)
  const recordLoading = ref(false)

  const recordHasMore = computed(() => {
    if (recordTotalPages.value <= 0) {
      return false
    }
    return lastRecordPageFetched.value < recordTotalPages.value
  })

  const selectedParent = computed(() => parentCoins.value[selectedParentIndex.value] ?? null)

  const selectedConfig = computed(() => subCoinOptions.value[selectedSubCoinIndex.value] ?? null)

  const selectedNetwork = computed<RechargeFlatNetworkOption | null>(() => {
    const cfg = selectedConfig.value
    return cfg ? toFlatOption(cfg) : null
  })

  async function loadRechargeNetworks(parentCoinName: string) {
    const raw = await get<Record<string, unknown>[]>('/uc/coin-network/recharge-networks', {
      coinName: parentCoinName,
    })
    const list = Array.isArray(raw) ? raw : []
    networkOptions.value = list.map(r => mapNetworkItem(r)).filter(n => n.id > 0)
    if (networkOptions.value.length > 0) {
      const stillValid = networkOptions.value.some(n => n.id === selectedNetworkId.value)
      if (!stillValid) {
        selectedNetworkId.value = networkOptions.value[0].id
      }
    } else {
      selectedNetworkId.value = 0
      subCoinOptions.value = []
    }
  }

  async function loadRechargeConfigs(parentCoinName: string, networkId: number) {
    subCoinsLoading.value = true
    try {
      const raw = await get<Record<string, unknown>[]>('/uc/coin-network/recharge-configs', {
        coinName: parentCoinName,
        networkId,
      })
      const list = Array.isArray(raw) ? raw : []
      subCoinOptions.value = list.map(r => mapConfigOption(r)).filter(c => c.networkConfigId > 0)
      if (selectedSubCoinIndex.value >= subCoinOptions.value.length) {
        selectedSubCoinIndex.value = 0
      }
    } finally {
      subCoinsLoading.value = false
    }
  }

  async function loadParentCoins() {
    loadingParents.value = true
    error.value = null
    try {
      const raw = await get<RechargeParentCoin[]>('/uc/coin-network/recharge-parents')
      const list = Array.isArray(raw) ? raw : []
      parentCoins.value = [...list].sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0))
      if (selectedParentIndex.value >= parentCoins.value.length) {
        selectedParentIndex.value = 0
      }
      if (parentCoins.value.length > 0) {
        await loadChildrenForParent(parentCoins.value[selectedParentIndex.value].name)
      } else {
        networkOptions.value = []
        subCoinOptions.value = []
      }
    } catch (e) {
      error.value = e instanceof Error ? e.message : '加载币种失败'
      parentCoins.value = []
      networkOptions.value = []
      subCoinOptions.value = []
      throw e
    } finally {
      loadingParents.value = false
    }
  }

  async function loadChildrenForParent(coinName: string) {
    childrenLoading.value = true
    error.value = null
    try {
      await loadRechargeNetworks(coinName)
      if (selectedNetworkId.value > 0) {
        await loadRechargeConfigs(coinName, selectedNetworkId.value)
      } else {
        subCoinOptions.value = []
      }
    } catch (e) {
      error.value = e instanceof Error ? e.message : '加载主网失败'
      networkOptions.value = []
      subCoinOptions.value = []
      throw e
    } finally {
      childrenLoading.value = false
    }
  }

  async function selectParent(index: number) {
    if (index < 0 || index >= parentCoins.value.length) {
      return
    }
    selectedParentIndex.value = index
    selectedSubCoinIndex.value = 0
    const p = parentCoins.value[index]
    if (p) {
      await loadChildrenForParent(p.name)
    }
  }

  async function selectNetwork(networkId: number) {
    if (!networkId || !networkOptions.value.some(n => n.id === networkId)) {
      return
    }
    selectedNetworkId.value = networkId
    selectedSubCoinIndex.value = 0
    const parent = selectedParent.value
    if (parent) {
      await loadRechargeConfigs(parent.name, networkId)
    }
  }

  function selectSubCoin(index: number) {
    if (index < 0 || index >= subCoinOptions.value.length) {
      return
    }
    selectedSubCoinIndex.value = index
  }

  async function createRechargeOrder(amount: string) {
    const opt = selectedConfig.value
    if (!opt) {
      throw new Error('请先选择充值网络与子币种')
    }
    orderSubmitting.value = true
    error.value = null
    try {
      const data = await postForm<RechargeOrderDetail>('/uc/recharge/create', {
        coinName: opt.coinName,
        networkConfigId: opt.networkConfigId,
        amount: amount.trim(),
      })
      currentOrder.value = data
      return data
    } catch (e) {
      error.value = e instanceof Error ? e.message : '创建订单失败'
      throw e
    } finally {
      orderSubmitting.value = false
    }
  }

  async function submitTxHash(orderNo: string, txHash: string) {
    hashSubmitting.value = true
    error.value = null
    try {
      const data = await postForm<RechargeOrderDetail>('/uc/recharge/submit-hash', {
        orderNo,
        txHash: txHash.trim(),
      })
      currentOrder.value = data
      return data
    } catch (e) {
      error.value = e instanceof Error ? e.message : '提交失败'
      throw e
    } finally {
      hashSubmitting.value = false
    }
  }

  function clearCurrentOrder() {
    currentOrder.value = null
  }

  async function loadRecords(refresh = false) {
    if (refresh) {
      lastRecordPageFetched.value = 0
      records.value = []
      recordTotalPages.value = 0
      recordTotalElements.value = 0
    }
    if (!refresh && !recordHasMore.value) {
      return
    }
    if (recordLoading.value) {
      return
    }
    const pageToFetch = refresh ? 1 : lastRecordPageFetched.value + 1
    recordLoading.value = true
    try {
      const data = await get<{
        content?: Record<string, unknown>[]
        totalElements?: number
        totalPages?: number
        number?: number
        size?: number
      }>('/uc/recharge/orders', {
        pageNo: pageToFetch,
        pageSize: recordPageSize,
      })
      const content = Array.isArray(data?.content) ? data.content : []
      const items = content.map(r => mapListItem(r as Record<string, unknown>))
      records.value = refresh ? items : [...records.value, ...items]
      recordTotalElements.value = Number(data?.totalElements ?? records.value.length)
      let totalPg = Number(data?.totalPages ?? 0)
      if (totalPg <= 0 && items.length > 0) {
        totalPg = 1
      }
      recordTotalPages.value = totalPg
      lastRecordPageFetched.value = pageToFetch
    } catch (e) {
      throw e instanceof Error ? e : new Error('加载记录失败')
    } finally {
      recordLoading.value = false
    }
  }

  async function fetchOrderDetail(orderNo: string) {
    return get<RechargeOrderDetail>('/uc/recharge/order', { orderNo })
  }

  return {
    parentCoins,
    networkOptions,
    subCoinOptions,
    selectedParentIndex,
    selectedNetworkId,
    selectedSubCoinIndex,
    loadingParents,
    childrenLoading,
    subCoinsLoading,
    error,
    currentOrder,
    orderSubmitting,
    hashSubmitting,
    records,
    recordLoading,
    recordHasMore,
    recordTotalElements,
    lastRecordPageFetched,
    selectedParent,
    selectedNetwork,
    selectedConfig,
    loadParentCoins,
    loadChildrenForParent,
    selectParent,
    selectNetwork,
    selectSubCoin,
    createRechargeOrder,
    submitTxHash,
    clearCurrentOrder,
    loadRecords,
    fetchOrderDetail,
  }
})
