import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { get, postForm } from '@/utils/request'
import { normalizeFuturesPairSymbol } from '@/utils/futuresSymbol'
import { useCoinsStore } from './coins'

// ── Types ──────────────────────────────────────────────────
export interface Ticker {
  symbol: string
  open: string
  high: string
  low: string
  close: string
  chg: string      // e.g. 0.0125 = 1.25%
  change: string
  volume: string
  turnover: string
  stockType: number
}

export interface OrderItem {
  price: string
  amount: string
  total: string
}

export interface OrderBook {
  ask: { items: OrderItem[] }
  bid: { items: OrderItem[] }
}

export interface KlineBar {
  time: number
  open: number
  high: number
  low: number
  close: number
  volume: number
}

// 止盈止损委托单（cutList 中的条目，type='SPOT_LIMIT'，isCut=1）
export interface CutOrder {
  id: string
  positionId: string
  type: string | number
  direction: string
  status: string | number
  createTime: number
  lossPrice?: number | string    // 止损触发价
  profitPrice?: number | string  // 止盈触发价
  triggerPrice?: string          // 触发价（原始字段）
  entrustPrice?: string          // 委托价
  volume?: string                // 数量
}

export interface Position {
  id: string
  direction: string          // BUY / SELL
  openPrice: string
  currentPrice: string
  leverage: number
  currentPosition: string
  availablePosition: string
  currentProfit: string
  usdtProfit: string
  currentMargin: string
  marginRate: string
  estimatedBlastPrice: string
  openTime: number
  coin: { symbol: string }
  profitPrice?: string       // 止盈价（可能为 null/0）
  lossPrice?: string         // 止损价（可能为 null/0）
  cutList?: CutOrder[]       // 止盈止损委托单列表
  /** 仓位模式：与 ContractOrder.positionType 一致，0 全仓 / 1 逐仓（接口可能附带） */
  positionType?: number
  patterns?: unknown
  experienceRecordId?: string | number | null
}

export interface ContractOrder {
  id: string
  direction: string
  type: number
  entrustType: string    // 'OPEN' | 'CLOSE'
  entrustPrice: string
  triggerPrice: string
  volume: string
  tradedVolume: string
  leverage: number
  lossPrice: string
  profitPrice: string
  status: number
  time: number
  createTime?: number    // 部分接口返回 createTime 而非 time
  symbol: string
  openType: number      // 0=市价 1=限价 2=计划委托
  positionType: number  // 0=全仓 1=逐仓
  positionId?: string   // 止盈止损单关联的仓位 ID
}

export interface HistoryPosition {
  id: string
  direction: string
  usdtOpenPrice: string       // 开仓价（旧字段）
  openPrice?: string          // 开仓价（新字段）
  tradedPrice: string         // 平仓成交价
  closePrice?: string         // 平仓均价（别名）
  leverage: string            // 字符串类型
  tradedVolume: string
  totalPosition?: string      // 委托总量
  volume?: string             // 委托总量（别名）
  closedPosition?: string     // 已成交量（别名）
  dealVolume?: string         // 已成交量（别名）
  principalAmount: string
  totalPrincipalAmount?: string // 保证金（别名）
  profitAndLoss: string       // 盈亏
  usdtProfit?: string         // 盈亏（别名）
  openFee: string
  closeFee: string
  commissionFee?: string      // 手续费（别名）
  createTime: number          // Long 毫秒时间戳
  openTime?: number           // 开仓时间（别名）
  usdtOpenTime?: number       // 开仓时间（别名）
  dealTime: number            // Long 毫秒时间戳
  closeTime?: number          // 平仓时间（别名）
  status: string
  closeType: number           // 1=市价 2=一键平 3=反向 4=止盈止损 5=爆仓
  symbol: string
  coinSymbol?: string         // 币对（别名）
  coin?: { symbol?: string; coinSymbol?: string }
  entrustType: string         // 'OPEN' | 'CLOSE'
  openType?: number           // 委托类型 0=市价 1=限价 2=计划
  type?: number               // 委托类型（别名）
  positionType?: number       // 0=全仓 1=分仓
  patterns?: string           // 'CROSSED' | 'ISOLATED'
  experienceRecordId?: string // 体验金标识
  triggerPrice?: string       // 触发价
  entrustPrice?: string       // 委托价
  profitPrice?: string        // 止盈价
  lossPrice?: string          // 止损价
}

export interface HistoryOrder {
  id: string
  direction: string
  entrustType: string       // 'OPEN' | 'CLOSE'
  type: string              // 'MARKET_PRICE' | 'LIMIT_PRICE' | 'SPOT_LIMIT'
  entrustPrice: string
  triggerPrice?: string     // 触发价
  tradedPrice: string       // 成交价
  usdtOpenPrice: string     // 开仓价
  openPrice?: string        // 开仓价（别名）
  volume?: string           // 委托量
  size?: string             // 委托量（别名）
  tradedVolume: string
  leverage: string
  profitAndLoss: string
  openFee: string
  closeFee: string
  principalAmount?: string  // 保证金
  profitPrice?: string      // 止盈价
  lossPrice?: string        // 止损价
  stopProfitPrice?: string  // 止盈价（别名）
  stopLossPrice?: string    // 止损价（别名）
  status: string
  createTime: number        // Long 毫秒时间戳
  usdtOpenTime?: number     // 委托时间（别名）
  dealTime: number          // Long 毫秒时间戳
  symbol: string
  coinSymbol?: string       // 币对（别名）
  positionType?: number     // 0=全仓 1=分仓
  patterns?: string         // 'CROSSED' | 'ISOLATED'
  experienceRecordId?: string
}

export interface FundingRecord {
  id: string
  amount: string        // 正=收入 负=支出
  createTime: string    // ISO字符串
  type: number          // TransactionType ordinal
  symbol: string        // 币种
  fee: string
  flag: number          // 0=支出 1=收入
}

export interface SymbolInfo {
  id: number
  symbol: string
  currentPrice: string
  leverage: string
  leverageType: number
  openFee: string
  closeFee: string
  takerFee?: string
  makerFee?: string
  minShare: string
  maxShare: string
  shareNumber?: string   // 合约面值（张）
  coinScale?: number     // 价格精度（与后端 coinScale 一致）
  minScale?: number      // 部分接口用 minScale 表示价格精度，优先 coinScale
  baseCoinScale?: number // 数量精度
  enableOpenBuy: number
  enableOpenSell: number
  maintenanceMarginRate: string
  intervalHour: number
  name?: string
  coinSymbol?: string
  baseSymbol?: string
  icon?: string
}

export interface CoinExtInfo {
  id?: number
  symbol: string
  nameCn?: string
  name?: string          // 后端有时用 name 代替 nameCn
  nameEn?: string
  icon?: string
  rank?: number
  marketCap?: string
  circulatingSupply?: string
  issuePrice?: number | string
  athPrice?: number | string
  athDate?: string
  whitepaper?: string
}

export interface FundingRateCurrent {
  fundingRate?: string | number
  rate?: string | number
  refreshTime?: number   // 毫秒时间戳，下次结算时间
}

export interface FundingRateHistory {
  id?: number
  contractId?: number
  fundingRate?: string | number
  rate?: string | number
  fundingTime?: number | string  // 毫秒时间戳或 ISO 字符串
}

export type KlineResolution = '1' | '5' | '15' | '30' | '60' | '240' | '1D'| '1W' | '1M' | '3M'

// 保证金模式：cross=全仓, split=分仓（后端 positionType: 0=全仓, 1=分仓）
export type MarginMode = 'cross' | 'split'

// 数量单位：lots=张, usdt=USDT, base=基础币
export type AmountUnit = 'lots' | 'usdt' | 'base'

export interface AccountInfo {
  totalBalance: number
  availableMargin: number
  usedMargin: number
  unrealizedPnl: number
  frozenMargin: number
}

// ── Store ──────────────────────────────────────────────────
export const useFuturesStore = defineStore('futures', () => {
  const symbol = ref('BTC/USDT')
  const ticker = ref<Ticker | null>(null)
  const orderBook = ref<OrderBook>({ ask: { items: [] }, bid: { items: [] } })
  const klines = ref<KlineBar[]>([])
  const klineResolution = ref<KlineResolution>('15')
  const symbolInfo = ref<SymbolInfo | null>(null)
  const positions = ref<Position[]>([])
  const currentOrders = ref<ContractOrder[]>([])
  const historyPositions = ref<HistoryPosition[]>([])
  const historyOrders = ref<HistoryOrder[]>([])
  const historyPositionPage = ref(1)
  const historyPositionNoMore = ref(false)
  const historyOrderPage = ref(1)
  const historyOrderNoMore = ref(false)
  const fundingRecords = ref<FundingRecord[]>([])
  const fundingRecordPage = ref(1)
  const fundingRecordNoMore = ref(false)
  const coinExtInfo = ref<CoinExtInfo | null>(null)
  const coinExtLoading = ref(false)
  const fundingRateCurrent = ref<FundingRateCurrent | null>(null)
  const fundingRateHistory = ref<FundingRateHistory[]>([])
  const fundingRateHistoryPage = ref(1)
  const fundingRateHistoryNoMore = ref(false)
  const leverage = ref(10)
  const marginMode = ref<MarginMode>('cross')
  const amountUnit = ref<AmountUnit>('base')
  const hideOtherSymbols = ref(false)
  const isSwitchingMode = ref(false)
  const accountInfo = ref<AccountInfo>({
    totalBalance: 0,
    availableMargin: 0,
    usedMargin: 0,
    unrealizedPnl: 0,
    frozenMargin: 0,
  })
  const loading = ref(false)
  const orderLoading = ref(false)
  const error = ref('')
  // 资金账户（SPOT）可用余额，来自 /swap/wallet-new/get 的 spotWallet.balance
  const spotAvailBalance = ref('0.00')
  // 合约账户可用余额
  const swapAvailBalance = ref('0.00')

  // All tickers for pair selector — sourced from shared coins store
  const coinsStore = useCoinsStore()
  const allTickers = computed(() => coinsStore.asTickers)

  const priceUp = computed(() => {
    if (!ticker.value) return true
    return parseFloat(ticker.value.chg) >= 0
  })

  const displaySymbol = computed(() => symbol.value.replace('/', '-'))

  // ── Fetch K-line ──
  async function fetchKlines(resolution: KlineResolution = klineResolution.value) {
    klineResolution.value = resolution
    const now = Date.now()  // 毫秒
    const spanMap: Record<string, number> = {
      '1': 60_000 * 200, '5': 300_000 * 200, '15': 900_000 * 200,
      '30': 1_800_000 * 200, '60': 3_600_000 * 200, '240': 14_400_000 * 200, '1D': 86_400_000 * 200,
    }
    const from = now - (spanMap[resolution] ?? 3_600_000 * 200)
    try {
      // Android 使用 FormUrlEncoded POST；响应是裸 List<List<String>>
      const data = await postForm<string[][]>('/market/swap/history', {
        symbol: symbol.value, from: String(from), to: String(now), resolution,
      })
      if (Array.isArray(data)) {
        klines.value = data
          .map(([time, open, high, low, close, volume]) => ({
            time: Number(time),
            open: parseFloat(open),
            high: parseFloat(high),
            low: parseFloat(low),
            close: parseFloat(close),
            volume: parseFloat(volume),
          }))
          .sort((a, b) => a.time - b.time)
      }
    } catch { /* silent */ }
  }

  // ── Fetch contract symbol info ──
  async function fetchSymbolInfo() {
    try {
      const data = await postForm<SymbolInfo>('/swap/symbol-info', { symbol: symbol.value })
      if (data) {
        symbolInfo.value = data
        // leverage 字段是 "1,30,50,75,100,120" 等，默认用 10x
        leverage.value = 10
      }
    } catch { /* silent */ }
  }

  // ── Fetch positions + wallet balance (requires auth) ──
  // Android 使用 /swap/wallet-new/get-with-positions?symbol= 带交易对参数获取仓位
  async function fetchPositions() {
    try {
      const data = await get<{
        currentPositionWithCutList: Position[]
        availableBalance: string
        currentCapital?: string
        balance?: string
        frozenMargin?: string
        frozenBalance?: string
        spotWallet: { balance: string }
      }>('/swap/wallet-new/get-with-positions', { symbol: symbol.value })
      if (data?.currentPositionWithCutList) positions.value = data.currentPositionWithCutList
      if (data?.spotWallet?.balance != null) spotAvailBalance.value = data.spotWallet.balance
      if (data?.availableBalance != null) swapAvailBalance.value = data.availableBalance

      // 同步账户信息（对齐 flutter FuturesAccountInfo.fromJson）
      const total = parseFloat(String(data?.currentCapital ?? data?.balance ?? '0')) || 0
      const frozen = parseFloat(String(data?.frozenMargin ?? data?.frozenBalance ?? '0')) || 0
      // 已用保证金 = 持仓本金之和（最准），其次取 frozenMargin
      const positionsMargin = (data?.currentPositionWithCutList ?? []).reduce(
        (s, p) => s + (parseFloat(p.currentMargin) || 0), 0)
      const usedMargin = positionsMargin > 0 ? positionsMargin : frozen
      const totalPnl = (data?.currentPositionWithCutList ?? []).reduce((s, p) => {
        const livePrice = parseFloat(p.currentPrice) || 0
        const openPrice = parseFloat(p.openPrice) || 0
        const vol = parseFloat(p.currentPosition) || 0
        const diff = p.direction === 'BUY' ? (livePrice - openPrice) : (openPrice - livePrice)
        return s + diff * vol
      }, 0)
      accountInfo.value = {
        totalBalance: total,
        availableMargin: Math.max(0, total - usedMargin),
        usedMargin,
        unrealizedPnl: totalPnl,
        frozenMargin: frozen,
      }
    } catch { /* silent */ }
  }

  // ── Fetch current orders ──
  // 合并 /swap/order/current 普通委托 + 每个仓位 cutList 中的止盈止损委托单
  async function fetchCurrentOrders() {
    try {
      const data = await get<{ content: ContractOrder[] }>('/swap/order/current', { pageNo: 1, pageSize: 100 })
      // 过滤掉 volume=0 的止盈止损孤立单（仓位已平但后端未自动撤销的残留）
      const regular: ContractOrder[] = (data?.content ?? []).filter(o =>
        !(parseFloat(o.volume) === 0 &&
          (parseFloat(o.profitPrice) > 0 || parseFloat(o.lossPrice) > 0))
      )
      // 从仓位 cutList 中提取止盈止损委托单，转换成 ContractOrder 格式展示
      const cutOrders: ContractOrder[] = []
      for (const pos of positions.value) {
        for (const cut of (pos.cutList ?? [])) {
          cutOrders.push({
            id: cut.id,
            direction: cut.direction ?? pos.direction,
            type: Number(cut.type),    // 3=止盈 4=止损
            entrustType: 'CLOSE',
            entrustPrice: cut.entrustPrice ?? '',
            triggerPrice: cut.triggerPrice ?? '',
            volume: cut.volume ?? pos.currentPosition,
            tradedVolume: '0',
            leverage: pos.leverage,
            lossPrice: Number(cut.type) === 4 ? (cut.triggerPrice ?? '') : '',
            profitPrice: Number(cut.type) === 3 ? (cut.triggerPrice ?? '') : '',
            status: 0,
            time: cut.createTime,
            createTime: cut.createTime,
            symbol: pos.coin?.symbol ?? '',
            openType: 0,
            positionType: 0,
            positionId: pos.id,
          })
        }
      }
      // cutOrders 去重（以 id 为基准），再合并
      const regularIds = new Set(regular.map(o => o.id))
      // 把 cutOrders 中已知 positionId 注入到 regular 同 id 的条目
      const cutIdToPosId = new Map(cutOrders.map(c => [c.id, c.positionId]))
      regular.forEach(o => { if (!o.positionId && cutIdToPosId.has(o.id)) o.positionId = cutIdToPosId.get(o.id) })
      const merged = [...regular, ...cutOrders.filter(c => !regularIds.has(c.id))]
      currentOrders.value = merged
    } catch { /* silent */ }
  }

  // ── Fetch history positions (历史仓位) ──
  async function fetchHistoryPositions(refresh = false) {
    if (!refresh && historyPositionNoMore.value) return
    if (refresh) { historyPositionPage.value = 1; historyPositionNoMore.value = false }
    try {
      const data = await get<{ content: HistoryPosition[]; last: boolean }>(
        '/swap/position/history',
        { pageNo: historyPositionPage.value, pageSize: 10 },
      )
      const list = data?.content ?? []
      if (refresh) {
        historyPositions.value = list
      } else {
        historyPositions.value = [...historyPositions.value, ...list]
      }
      if (data?.last || list.length < 10) historyPositionNoMore.value = true
      else historyPositionPage.value++
    } catch { /* silent */ }
  }

  // ── Fetch history orders (历史委托) ──
  async function fetchHistoryOrders(refresh = false) {
    if (!refresh && historyOrderNoMore.value) return
    if (refresh) { historyOrderPage.value = 1; historyOrderNoMore.value = false }
    try {
      const data = await get<{ content: HistoryOrder[]; last: boolean }>(
        '/swap/order/history-all',
        { pageNo: historyOrderPage.value, pageSize: 10 },
      )
      const list = data?.content ?? []
      if (refresh) {
        historyOrders.value = list
      } else {
        historyOrders.value = [...historyOrders.value, ...list]
      }
      if (data?.last || list.length < 10) historyOrderNoMore.value = true
      else historyOrderPage.value++
    } catch { /* silent */ }
  }

  // ── Fetch funding records (资金流水) ──
  async function fetchFundingRecords(refresh = false, excludeSpot = 1) {
    if (!refresh && fundingRecordNoMore.value) return
    if (refresh) { fundingRecordPage.value = 1; fundingRecordNoMore.value = false }
    try {
      const data = await postForm<{ content: FundingRecord[]; last: boolean }>(
        '/uc/asset/transaction/all',
        {
          pageNo: String(fundingRecordPage.value),
          pageSize: '10',
          excludeSpot: String(excludeSpot),
        },
      )
      const list = data?.content ?? []
      if (refresh) {
        fundingRecords.value = list
      } else {
        fundingRecords.value = [...fundingRecords.value, ...list]
      }
      if (data?.last || list.length < 10) fundingRecordNoMore.value = true
      else fundingRecordPage.value++
    } catch { /* silent */ }
  }

  // ── Fetch coin ext info (币种资料) ──
  // GET /contract/coin-ext/detail?symbol=BTC
  async function fetchCoinExtInfo() {
    const baseCoin = symbol.value.split('/')[0]
    coinExtLoading.value = true
    try {
      const data = await get<CoinExtInfo | { data?: CoinExtInfo; result?: CoinExtInfo }>(
        '/contract/coin-ext/detail', { symbol: baseCoin }
      )
      let info: CoinExtInfo | null = null
      if (data && typeof data === 'object') {
        if ('symbol' in data) {
          info = data as CoinExtInfo
        } else {
          const d = data as { data?: CoinExtInfo; result?: CoinExtInfo }
          info = d.data ?? d.result ?? null
        }
      }
      coinExtInfo.value = info
    } catch { /* silent */ } finally {
      coinExtLoading.value = false
    }
  }

  // ── Fetch current funding rate (当前资金费率) ──
  // GET /swap/funding-rate/current?contractCoinId=XXX
  async function fetchFundingRateCurrent() {
    if (!symbolInfo.value?.id) return
    try {
      const data = await get<FundingRateCurrent | { data?: FundingRateCurrent }>(
        '/swap/funding-rate/current', { contractCoinId: symbolInfo.value.id }
      )
      if (data && typeof data === 'object') {
        if ('fundingRate' in data || 'rate' in data) {
          fundingRateCurrent.value = data as FundingRateCurrent
        } else {
          const d = data as { data?: FundingRateCurrent }
          fundingRateCurrent.value = d.data ?? null
        }
      }
    } catch { /* silent */ }
  }

  // ── Fetch funding rate history (历史资金费率) ──
  // GET /swap/funding-rate/history — 每次拉取最近7天，pageSize=100 保证覆盖完整
  async function fetchFundingRateHistory(refresh = false) {
    if (!symbolInfo.value?.id) return
    if (!refresh && fundingRateHistoryNoMore.value) return
    if (refresh) { fundingRateHistoryPage.value = 1; fundingRateHistoryNoMore.value = false }
    // 构建7天日期范围（与后端 FundingRateForm 的 startDate/endDate 对应）
    const now = new Date()
    const sevenDaysAgo = new Date(now.getTime() - 7 * 24 * 3600 * 1000)
    const fmtDate = (d: Date) =>
      `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`
    try {
      const data = await get<
        { content?: FundingRateHistory[]; last?: boolean } | FundingRateHistory[]
      >('/swap/funding-rate/history', {
        contractCoinId: symbolInfo.value.id,
        pageNo: fundingRateHistoryPage.value,
        pageSize: 100,
        startDate: fmtDate(sevenDaysAgo),
        endDate: fmtDate(now),
      })
      let list: FundingRateHistory[] = []
      let isLast = false
      if (Array.isArray(data)) {
        list = data
        isLast = list.length < 100
      } else if (data && typeof data === 'object') {
        list = (data as { content?: FundingRateHistory[] }).content ?? []
        isLast = (data as { last?: boolean }).last ?? list.length < 100
      }
      if (refresh) {
        fundingRateHistory.value = list
      } else {
        fundingRateHistory.value = [...fundingRateHistory.value, ...list]
      }
      if (isLast) fundingRateHistoryNoMore.value = true
      else fundingRateHistoryPage.value++
    } catch { /* silent */ }
  }

  // ── Place order ──
  // direction: 0=开多(BUY) 1=开空(SELL)
  // type: 0=市价 1=限价 2=计划委托
  async function placeOrder(params: {
    direction: 0 | 1
    type: 0 | 1 | 2
    entrustPrice?: string
    triggerPrice?: string
    volume: string
    lossPrice?: string
    profitPrice?: string
  }) {
    if (!symbolInfo.value) return false
    orderLoading.value = true
    error.value = ''
    try {
      const orderData = await postForm<{ positionId: number } | null>('/swap/order/open/v3', {
        contractCoinId: String(symbolInfo.value.id),
        type: String(params.type),
        direction: String(params.direction),
        entrustPrice: params.entrustPrice ?? '',
        triggerPrice: params.triggerPrice ?? '',
        volume: params.volume,
        leverage: String(leverage.value),
        lossPrice: params.lossPrice ?? '',
        profitPrice: params.profitPrice ?? '',
        positionType: marginMode.value === 'split' ? '1' : '0',
      })
      // 开仓成功后，若设置了止盈止损，调用 cut-position 创建委托单
      // 后端有频率限制，需等待后重试
      const posId = orderData?.positionId
      if (posId && (params.lossPrice || params.profitPrice)) {
        const cutPayload = {
          positionId: String(posId),
          profitPrice: params.profitPrice ?? '0',
          profitEntrustPrice: '0.0',
          lossPrice: params.lossPrice ?? '0',
          lossEntrustPrice: '0.0',
        }
        for (const delay of [1500, 2000, 3000]) {
          await new Promise(r => setTimeout(r, delay))
          try {
            await postForm('/swap/order/cut-position', cutPayload)
            break  // 成功则退出重试
          } catch { /* 继续重试 */ }
        }
      }
      await fetchPositions()
      await fetchCurrentOrders()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '下单失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Close all positions (一键平仓) ──
  async function closeAllPositions() {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/close-all-coins', {})
      await fetchPositions()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '一键平仓失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Market close (市价平仓：/swap/order/close，type=0=MARKET_PRICE) ──
  async function closePosition(positionId: string, volume: string) {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/close', { positionId, volume, type: '0', entrustPrice: '0', triggerPrice: '0' })
      await fetchPositions()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '平仓失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Limit close (限价平仓：/swap/order/close，type=1=LIMIT_PRICE) ──
  async function closeLimitPosition(positionId: string, entrustPrice: string, volume: string) {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/close', { positionId, entrustPrice, volume, type: '1', triggerPrice: '0' })
      await fetchPositions()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '平仓失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Conditional market close (市价委托平仓：/swap/order/close, type=2, entrustPrice=0) ──
  async function closeConditionalMarket(positionId: string, triggerPrice: string, volume: string) {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/close', { positionId, volume, type: '2', entrustPrice: '0', triggerPrice })
      await fetchPositions()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '委托平仓失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Conditional limit close (限价委托平仓：/swap/order/close, type=2, entrustPrice=限价) ──
  async function closeConditionalLimit(positionId: string, triggerPrice: string, entrustPrice: string, volume: string) {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/close', { positionId, entrustPrice, volume, type: '2', triggerPrice })
      await fetchPositions()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '委托平仓失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Cancel order ──
  async function cancelOrder(entrustId: string) {
    try {
      await postForm('/swap/order/cancel', { entrustId })
      await fetchCurrentOrders()
    } catch { /* silent */ }
  }

  // ── Cancel all current orders (全部撤单) ──
  async function cancelAllOrders() {
    const ids = currentOrders.value
      .map(o => parseInt(o.id, 10))
      .filter(n => !isNaN(n))
    if (!ids.length) {
      error.value = '暂无可撤销的委托'
      return false
    }
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/cancel-by-ids', { entrustIds: JSON.stringify(ids) })
      await fetchCurrentOrders()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '撤单失败'
      await fetchCurrentOrders()
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Reverse open position (一键反手) ──
  async function reversePosition(positionId: string) {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/close-and-open', { positionId })
      await fetchPositions()
      await fetchCurrentOrders()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '反手失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Set margin mode (全仓/逐仓/分仓) ──
  // 后端只区分合仓(0) / 分仓(1)
  async function setMarginMode(mode: MarginMode) {
    if (mode === marginMode.value) return true
    isSwitchingMode.value = true
    error.value = ''
    try {
      const serverType = mode === 'split' ? 1 : 0
      await postForm('/swap/wallet-new/modifyType', { positionType: String(serverType) })
      marginMode.value = mode
      // 切换成功后重新拉取杠杆
      await fetchLeverage().catch(() => {})
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '切换保证金模式失败'
      return false
    } finally {
      isSwitchingMode.value = false
    }
  }

  function setAmountUnit(unit: AmountUnit) { amountUnit.value = unit }
  function toggleHideOtherSymbols() { hideOtherSymbols.value = !hideOtherSymbols.value }

  // ── Modify TP/SL (修改止盈止损) ──
  async function modifyTpSl(positionId: string, profitPrice: string, lossPrice: string) {
    orderLoading.value = true
    error.value = ''
    try {
      await postForm('/swap/order/cut-position', {
        positionId,
        profitPrice: profitPrice || '0',
        profitEntrustPrice: '0.0',
        lossPrice: lossPrice || '0',
        lossEntrustPrice: '0.0',
      })
      await fetchPositions()
      await fetchCurrentOrders()
      return true
    } catch (e) {
      error.value = e instanceof Error ? e.message : '修改止盈止损失败'
      return false
    } finally {
      orderLoading.value = false
    }
  }

  // ── Fetch account leverage ──
  async function fetchLeverage() {
    if (!symbolInfo.value) return
    try {
      const data = await postForm<number>('/swap/wallet-new/getLeverage', {
        contractId: String(symbolInfo.value.id),
      })
      if (data != null && Number(data) > 0) leverage.value = Number(data)
    } catch { /* silent */ }
  }

  // ── Modify leverage ──
  async function modifyLeverage(lv: number) {
    leverage.value = lv
    if (!symbolInfo.value) return
    try {
      await postForm('/swap/wallet-new/modifyLeverage', {
        contractId: String(symbolInfo.value.id),
        leverage: String(lv),
      })
    } catch { /* silent */ }
  }

  // ── Set symbol ──
  function setSymbol(s: string) {
    symbol.value = s
  }

  // ── Load all data for current symbol ──
  async function init(sym: string) {
    symbol.value = normalizeFuturesPairSymbol(sym)
    loading.value = true
    await Promise.all([
      coinsStore.fetchCoins(),
      fetchSymbolInfo(),
    ])
    loading.value = false
  }

  return {
    symbol, displaySymbol, ticker, orderBook, klines, klineResolution,
    symbolInfo, positions, currentOrders, leverage, loading, orderLoading, error,
    allTickers, priceUp, spotAvailBalance, swapAvailBalance,
    historyPositions, historyOrders, historyPositionNoMore, historyOrderNoMore,
    fundingRecords, fundingRecordNoMore,
    coinExtInfo, coinExtLoading,
    fundingRateCurrent, fundingRateHistory, fundingRateHistoryNoMore,
    marginMode, amountUnit, hideOtherSymbols, isSwitchingMode, accountInfo,
    init, fetchKlines, fetchSymbolInfo,
    fetchPositions, fetchCurrentOrders, fetchHistoryPositions, fetchHistoryOrders,
    fetchFundingRecords,
    fetchCoinExtInfo, fetchFundingRateCurrent, fetchFundingRateHistory,
    placeOrder, closePosition, closeLimitPosition, closeConditionalMarket, closeConditionalLimit,
    closeAllPositions, cancelOrder, cancelAllOrders, reversePosition,
    modifyTpSl, setSymbol, setMarginMode, setAmountUnit, toggleHideOtherSymbols,
    fetchLeverage, modifyLeverage,
  }
})
