import supa from '@/components/supadb/aksupainstance.uts'
import { getCurrentUserId } from '@/utils/store.uts'

/**
 * 配送模块数据服务 (Express Service)
 * 依据: pages/mall/delivery/doc/需求文档/
 * 功能: 对接 Supabase 生产表 (platform_express_*)
 */

export interface MockOrder {
  id?: string
  order_no: string
  user_id?: string
  merchant_id?: string
  status: string
  created_at: string
  receiver_name: string
  receiver_masked_phone: string
  address: string
  amount: string
  carrier: string
  tracking_no: string
  last_synced_at?: string
  current_status_text?: string
}

export interface MockTrackingEvent {
  event_id: string
  event_time: string
  event_code: string
  event_text: string
  status_code: string
  node_name?: string
  location?: string
  evidence_urls: string[]
  raw_payload?: string
}

export interface MockWebhookLog {
  time: string
  carrier: string
  tracking_no: string
  event_code: string
  success: boolean
  result_text: string
  payload: UTSJSONObject
}

/**
 * 集中管理物流常量与映射
 */
export const LogisticsConstants = {
  // 8 大标准配送状态映射
  STATUS_MAP: {
    'ORDER_PLACED': '已下单',
    'SHIPPED': '已发货',
    'PENDING': '待发货',
    'IN_TRANSIT': '运输中',
    'OUT_FOR_DELIVERY': '派送中',
    'READY_FOR_PICKUP': '待取件',
    'DELIVERED': '已签收',
    'EXCEPTION': '异常',
    'RETURNED': '退回/退件'
  } as UTSJSONObject,

  // 状态对应图标
  STATUS_ICONS: {
    'ORDER_PLACED': '📦',
    'SHIPPED': '🚚',
    'IN_TRANSIT': '🛤️',
    'OUT_FOR_DELIVERY': '🛵',
    'READY_FOR_PICKUP': '🏪',
    'DELIVERED': '✅',
    'EXCEPTION': '❗',
    'RETURNED': '🔄'
  } as UTSJSONObject,

  // 时间线简短标签
  STATUS_LABELS_SHORT: {
    'ORDER_PLACED': '下单',
    'SHIPPED': '出库',
    'IN_TRANSIT': '运输',
    'OUT_FOR_DELIVERY': '派送',
    'READY_FOR_PICKUP': '待取',
    'DELIVERED': '完成',
    'EXCEPTION': '异常',
    'RETURNED': '退回'
  } as UTSJSONObject,

  // 常用快递公司列表
  CARRIERS: [
    { label: '顺丰速运', value: '顺丰速运' },
    { label: '圆通速递', value: '圆通速递' },
    { label: '中通快递', value: '中通快递' },
    { label: '申通快递', value: '申通快递' },
    { label: '韵达快递', value: '韵达快递' },
    { label: '京东快递', value: '京东快递' }
  ] as UTSJSONObject[]
}

class MockService {
  // 全局 Mock 配置项
  public isTestMode: boolean = true
  public autoPush: boolean = true
  public mockUrl: string = 'http://192.168.1.100:3000/mock/v1'

  constructor() {}

  async getMockOrders(): Promise<MockOrder[]> {
    const userId = getCurrentUserId()
    console.log('DEBUG: currentUserId =', userId)
    
    // 方案 1：直接通过运单表关联订单表的 user_id 过滤
    // 注意：确保 ml_orders!inner(*) 强制关联，否则 eq 会失效
    const query = supa.from('platform_express_waybills')
      .select('*, ml_orders!inner(*)')
      .order('created_at', { ascending: false })

    if (userId != '' && userId != 'admin') {
      console.log('DEBUG: filtering by ml_orders.user_id =', userId)
      query.eq('ml_orders.user_id', userId)
    }

    const { data: d1, error: e1 } = await query.execute()

    // 如果请求本身报错，先记录并尝试降级策略
    if (e1 != null) {
      console.error('DEBUG: primary query error =', e1)
    }

    // 规范化返回的数据为数组（Supabase 客户端在某些情况下可能返回包装对象）
    let resultArray: Array<UTSJSONObject> | null = null
    if (Array.isArray(d1)) {
      resultArray = d1 as Array<UTSJSONObject>
    } else if (d1 != null && (d1 as any).data && Array.isArray((d1 as any).data)) {
      resultArray = (d1 as any).data as Array<UTSJSONObject>
    }

    // 方案 2（保底）：如果方案 1 没查到数据，可能是因为某些运单没有关联订单，或者 !inner 过滤太严格
    if (resultArray == null || resultArray.length === 0) {
      console.log('DEBUG: first query empty or error, trying fallback...')
      const query2 = supa.from('platform_express_waybills')
        .select('*, ml_orders(*)')
        .order('created_at', { ascending: false })

      const { data: d2, error: e2 } = await query2.execute()
      if (e2 != null) {
        console.error('DEBUG: fallback query error =', e2)
      }

      const allData = Array.isArray(d2) ? (d2 as Array<UTSJSONObject>) : ((d2 && (d2 as any).data && Array.isArray((d2 as any).data)) ? (d2 as any).data : null)

      if (allData != null) {
        // 在内存中过滤归属于当前用户的订单（用于数据还没同步完全的情况）
        const filtered = allData.filter((item: UTSJSONObject): boolean => {
          if (userId == '' || userId == 'admin') return true

          let ml: UTSJSONObject | null = null
          const mlData = item['ml_orders']
          if (mlData instanceof Array && (mlData as Array<any>).length > 0) {
            ml = (mlData as Array<UTSJSONObject>)[0]
          } else if (!(mlData instanceof Array)) {
            ml = mlData as UTSJSONObject
          }

          try {
            return ml != null && (ml as any).user_id == userId
          } catch (err) {
            return false
          }
        })
        console.log('DEBUG: filtered in memory length =', filtered.length)
        return this.mapDataToOrders(filtered)
      }
    }

    console.log('DEBUG: query result data length =', resultArray ? resultArray.length : 0)
    return this.mapDataToOrders(resultArray)
  }

  // 抽离数据映射逻辑
  private mapDataToOrders(data: Array<UTSJSONObject> | null): MockOrder[] {
    if (data == null) return []
    return data.map((item: UTSJSONObject): MockOrder => {
      let ml: UTSJSONObject | null = null
      const mlData = item['ml_orders']
      if (mlData != null) {
        if (mlData instanceof Array && (mlData as Array<any>).length > 0) {
          ml = (mlData as Array<UTSJSONObject>)[0]
        } else if (!(mlData instanceof Array)) {
          ml = mlData as UTSJSONObject
        }
      }

      return {
        id: item['id'] as string,
        order_no: item['order_no'] as string || (ml != null ? ml['order_no'] as string : ''),
        status: item['current_status_code'] as string,
        created_at: this.formatDBTime(item['created_at'] as string),
        receiver_name: (ml != null ? ml['receiver_name'] as string : '测试用户'),
        receiver_masked_phone: this.maskPhone(ml != null ? ml['receiver_phone'] as string : '138****0000'),
        address: (ml != null ? ml['address'] as string : '系统模拟地址'),
        amount: (ml != null ? ml['amount'] as string : '0.00'),
        carrier: item['carrier'] as string,
        tracking_no: item['tracking_no'] as string,
        merchant_id: (ml != null ? ml['merchant_id'] as string : ''),
        last_synced_at: this.formatDBTime(item['last_synced_at'] as string),
        current_status_text: item['current_status_text'] as string
      } as MockOrder
    })
  }

  async getMockTracking(id: string): Promise<MockTrackingEvent[]> {
    if (!id || id == '') return []
    
    // 1. 穿透式查询：先寻找运单 ID
    let waybillId: string | null = null
    let trackingNo: string | null = null

    // 尝试按订单号找
    const { data: b1 } = await supa.from('platform_express_waybills').select('id,tracking_no').eq('order_no', id).execute()
    if (b1 != null && (b1 as Array<any>).length > 0) {
      const row = (b1 as Array<UTSJSONObject>)[0]
      waybillId = row['id'] as string
      trackingNo = row['tracking_no'] as string
    } else {
      // 尝试按运单号找
      const { data: b2 } = await supa.from('platform_express_waybills').select('id,tracking_no').eq('tracking_no', id).execute()
      if (b2 != null && (b2 as Array<any>).length > 0) {
        const row = (b2 as Array<UTSJSONObject>)[0]
        waybillId = row['id'] as string
        trackingNo = row['tracking_no'] as string
      }
    }

    if (waybillId != null) {
      // 2. 查该运单聚合的所有轨迹
      // 同样为了稳定，分两次查或使用简单的 or (如果 or 有效)
      let allEvents = [] as MockTrackingEvent[]
      
      const { data: events, error } = await supa.from('platform_express_tracking_events')
        .select('*')
        .eq('waybill_id', waybillId!)
        .order('event_time', { ascending: false })
        .execute()
      
      if (events != null) {
        allEvents = this.mapToEvents(events as Array<UTSJSONObject>)
      }
      
      // 如果按 UUID 没查到，尝试按单号补查
      if (allEvents.length == 0 && trackingNo != null) {
        const { data: events2 } = await supa.from('platform_express_tracking_events')
          .select('*')
          .eq('tracking_no', trackingNo!)
          .order('event_time', { ascending: false })
          .execute()
        if (events2 != null) {
          allEvents = this.mapToEvents(events2 as Array<UTSJSONObject>)
        }
      }
      return allEvents
    }

    // 3. 最后的保底：直接尝试在轨迹表中匹配 (单号直接搜索)
    const { data: directEvents } = await supa.from('platform_express_tracking_events')
      .select('*')
      .eq('tracking_no', id)
      .order('event_time', { ascending: false })
      .execute()

    if (directEvents != null && (directEvents as Array<any>).length > 0) {
      return this.mapToEvents(directEvents as Array<UTSJSONObject>)
    }

    return []
  }

  /**
   * 管理/调试用：获取所有运单（不做用户过滤）
   */
  async getAllOrders(): Promise<MockOrder[]> {
    const { data, error } = await supa.from('platform_express_waybills')
      .select('*, ml_orders(*)')
      .order('created_at', { ascending: false })
      .execute()

    if (error != null) {
      console.error('Fetch all orders error:', error)
      return []
    }

    const list = data as Array<UTSJSONObject>
    return this.mapDataToOrders(list)
  }

  /**
   * 模拟各种物流场景 (生成生产测试数据)
   */
  async runScenario(trackingNo: string, type: string) {
    // 查找运单 (使用通用的单号查询逻辑)
    const { data: waybills } = await supa.from('platform_express_waybills')
      .select('id,carrier,tracking_no')
      .eq('tracking_no', trackingNo)
      .execute()
    
    if (waybills == null || (waybills as Array<any>).length === 0) {
      console.error('Scenario Error: Waybill not found', trackingNo)
      return
    }

    const waybill = (waybills as Array<UTSJSONObject>)[0]
    const waybillId = waybill['id'] as string
    const carrier = waybill['carrier'] as string
    
    if (waybillId == null || waybillId == "") {
      console.error('Scenario Error: Waybill ID is null')
      return
    }

    // 模拟不同步长的数据注入
    const now = new Date().toISOString()
    const events = [] as any[]
    
    if (type === 'full') {
      events.push({ waybill_id: waybillId, carrier, tracking_no: trackingNo, event_time: now, event_code: 'SIGNED', event_text: '用户已签收', status_code: 'DELIVERED', dedupe_key: 'SCENARIO_SIG_'+Date.now() })
      events.push({ waybill_id: waybillId, carrier, tracking_no: trackingNo, event_time: now, event_code: 'SENT', event_text: '派送中', status_code: 'OUT_FOR_DELIVERY', dedupe_key: 'SCENARIO_SEN_'+Date.now() })
    } else if (type === 'standard') {
      events.push({ waybill_id: waybillId, carrier, tracking_no: trackingNo, event_time: now, event_code: 'ARRIVED_HUB', event_text: '快件已到达中转站', status_code: 'IN_TRANSIT', dedupe_key: 'SCENARIO_HUB_'+Date.now() })
    } else if (type === 'exception') {
      events.push({ waybill_id: waybillId, carrier, tracking_no: trackingNo, event_time: now, event_code: 'FAILED', event_text: '包裹由于地址不详正在退回', status_code: 'EXCEPTION', dedupe_key: 'SCENARIO_ERR_'+Date.now() })
    }

    if (events.length > 0) {
      // 1. 插入轨迹节点
      await supa.from('platform_express_tracking_events').insert(events).execute()
      
      // 2. 同步更新主表状态 (以最新一个节点为准)
      const latest = events[0] as UTSJSONObject
      await supa.from('platform_express_waybills').update({
        current_status_code: latest['status_code'] as string,
        current_status_text: latest['event_text'] as string,
        last_synced_at: now
      }).eq('id', waybillId).execute()
    }
  }

  private mapToEvents(list: Array<UTSJSONObject>): MockTrackingEvent[] {
    return list.map((e: UTSJSONObject): MockTrackingEvent => {
      // 解析 evidence_urls (JSONB)
      let urls = [] as string[]
      const rawUrls = e['evidence_urls']
      if (rawUrls instanceof Array) {
        urls = rawUrls as string[]
      }

      return {
        event_id: e['id'] as string,
        event_time: this.formatDBTime(e['event_time'] as string),
        event_code: e['event_code'] as string || '',
        event_text: e['event_text'] as string || '',
        status_code: e['status_code'] as string || '',
        node_name: e['node_name'] as string || '',
        location: e['location'] as string || '',
        evidence_urls: urls,
        raw_payload: JSON.stringify(e['raw_payload'] || {})
      } as MockTrackingEvent
    })
  }

  // 绑定发货逻辑：写库
  async bindShipment(orderNo: string, carrier: string, trackingNo: string): Promise<boolean> {
    // 1. 先查找订单主体
    const { data: orderData } = await supa.from('ml_orders').select('id,order_no').eq('order_no', orderNo).single().execute()
    const orderId = (orderData != null) ? orderData['id'] as string : null

    // 2. 创建或更新运单记录
    // 先查询是否存在
    const { data: existingWaybills } = await supa.from('platform_express_waybills').select('id').eq('order_no', orderNo).execute()
    let waybillIdForEvent: string | null = null
    
    const waybillPayload = {
      order_id: orderId,
      order_no: orderNo,
      carrier: carrier,
      tracking_no: trackingNo,
      current_status_code: 'SHIPPED',
      current_status_text: '商家已发货',
      last_synced_at: new Date().toISOString(),
      source: 'mock'
    } as UTSJSONObject

    if (existingWaybills != null && (existingWaybills as Array<any>).length > 0) {
      // 更新
      const waybillRow = (existingWaybills as Array<UTSJSONObject>)[0]
      waybillIdForEvent = waybillRow['id'] as string
      await supa.from('platform_express_waybills').update(waybillPayload).eq('id', waybillIdForEvent).execute()
    } else {
      // 插入
      const { data: newWaybill, error: insError } = await supa.from('platform_express_waybills').insert(waybillPayload).select().single().execute()
      if (insError != null) {
        console.error('Insert waybill error:', insError)
        return false
      }
      if (newWaybill != null) {
        waybillIdForEvent = (newWaybill as UTSJSONObject)['id'] as string
      }
    }

    if (waybillIdForEvent == null) {
      console.error('Bind shipment error: Failed to get waybill ID')
      return false
    }

    // 2.5 更新订单表状态
    const { error: oError } = await supa.from('ml_orders').update({
      order_status: 3, // SHIPPED
      shipping_status: 2, // 已向物流公司提交
      shipped_at: new Date().toISOString()
    }).eq('order_no', orderNo).execute()
    
    if (oError != null) {
      console.error('Update ml_orders error:', oError)
      // 继续执行，因为运单记录已经拉起
    }

    // 3. 产生初始轨迹
    await supa.from('platform_express_tracking_events').insert({
      waybill_id: waybillIdForEvent,
      carrier: carrier,
      tracking_no: trackingNo,
      event_time: new Date().toISOString(),
      event_code: 'CREATED',
      event_text: '商家已发货，等待快递公司揽收',
      status_code: 'SHIPPED',
      dedupe_key: 'INIT_' + orderNo + '_' + Date.now(),
      evidence_urls: []
    }).execute()

    return true
  }

  // 用户确认取件逻辑
  async confirmReceipt(orderNo: string): Promise<boolean> {
    // 1. 获取运单信息
    const { data: waybills } = await supa.from('platform_express_waybills')
      .select('id,carrier,tracking_no')
      .eq('order_no', orderNo)
      .execute()
    
    if (waybills == null || (waybills as Array<any>).length === 0) {
      return false
    }
    
    const waybill = (waybills as Array<UTSJSONObject>)[0]
    const waybillId = waybill['id'] as string
    const carrier = waybill['carrier'] as string
    const trackingNo = waybill['tracking_no'] as string
    const now = new Date().toISOString()

    // 2. 更新运单主表状态
    await supa.from('platform_express_waybills').update({
      current_status_code: 'DELIVERED',
      current_status_text: '用户已确认取件',
      last_synced_at: now
    }).eq('id', waybillId).execute()

    // 3. 更新订单主表状态 (DEVLIVERED = 4)
    await supa.from('ml_orders').update({
      order_status: 4,
      delivered_at: now
    }).eq('order_no', orderNo).execute()

    // 4. 插入取件轨迹
    await supa.from('platform_express_tracking_events').insert({
      waybill_id: waybillId,
      carrier: carrier,
      tracking_no: trackingNo,
      event_time: now,
      event_code: 'USER_PICKUP',
      event_text: '用户已确认取件，感谢使用',
      status_code: 'DELIVERED',
      dedupe_key: 'CONFIRM_' + orderNo + '_' + Date.now(),
      evidence_urls: []
    }).execute()

    return true
  }

  /**
   * 核心功能：模拟第三方回调接口 (写库版)
   */
  async pushWebhookData(payload: UTSJSONObject): Promise<boolean> {
    const tracking_no = (payload['mailNo'] != null) ? payload['mailNo'] as string : (payload['tracking_no'] as string)
    const yto_status = (payload['infoContent'] != null) ? payload['infoContent'] as string : (payload['status_code'] as string)
    const event_text = (payload['remark'] != null) ? payload['remark'] as string : (payload['event_text'] as string)
    const order_no = payload['txLogisticId'] as string || ''
    const carrier = payload['carrier'] as string || '圆通速递'

    console.log('--- Webhook Push Start ---')
    console.log('Target:', tracking_no, order_no)

    // 1. 记录原始日志 (Raw)
    await supa.from('platform_express_event_raw').insert({
      carrier: carrier,
      tracking_no: tracking_no,
      body: payload,
      received_at: new Date().toISOString(),
      signature_valid: true
    }).execute()

    // 2. 查找运单 ID (手动分步查询)
    let final_id: string = ""
    
    // 尝试按单号
    const res1 = await supa.from('platform_express_waybills').select('id').eq('tracking_no', tracking_no).execute()
    const list1 = res1.data as Array<UTSJSONObject> | null
    if (list1 != null && list1.length > 0) {
      final_id = list1[0]['id'] as string
    } else {
      // 尝试按订单号
      const res2 = await supa.from('platform_express_waybills').select('id').eq('order_no', order_no).execute()
      const list2 = res2.data as Array<UTSJSONObject> | null
      if (list2 != null && list2.length > 0) {
        final_id = list2[0]['id'] as string
      }
    }

    if (final_id == "") {
      console.error('CRITICAL: Waybill NOT found in DB')
      return false
    }

    console.log('Found Waybill ID:', final_id)

    // 状态映射 (根据 状态映射表.md 规范)
    let status_code = 'IN_TRANSIT'
    if (yto_status === 'GOT' || yto_status === 'SEND' || yto_status === 'TRANSIT') {
      status_code = 'IN_TRANSIT'
    } else if (yto_status === 'SENT') {
      status_code = 'OUT_FOR_DELIVERY'
    } else if (yto_status === 'PICKUP') {
      status_code = 'READY_FOR_PICKUP'
    } else if (yto_status === 'SIGNED' || yto_status === 'DELIVERED') {
      status_code = 'DELIVERED'
    } else if (yto_status === 'FAILED' || yto_status === 'EXCEPTION') {
      status_code = 'EXCEPTION'
    } else if (yto_status === 'RETURNED') {
      status_code = 'RETURNED'
    } else {
      // 容错：如果是已知的 8 大状态之一，直接使用
      const validStates = ['ORDER_PLACED', 'SHIPPED', 'IN_TRANSIT', 'OUT_FOR_DELIVERY', 'READY_FOR_PICKUP', 'DELIVERED', 'EXCEPTION', 'RETURNED']
      if (validStates.indexOf(yto_status) > -1) {
        status_code = yto_status
      }
    }

    // 3. 执行更新 (确保 ID 不为空)
    const updateRes = await supa.from('platform_express_waybills').update({
      current_status_code: status_code,
      current_status_text: event_text,
      last_synced_at: new Date().toISOString()
    }).eq('id', final_id).execute()
    
    if (updateRes.error != null) {
      console.error('Update Waybill Error:', updateRes.error)
    }

    // 4. 插入轨迹 (确保 ID 不为空)
    const acceptTimeRaw = payload['acceptTime'] as string
    let eventTimeToStore = new Date().toISOString()
    if (acceptTimeRaw != null && acceptTimeRaw != '') {
      const normalized = (acceptTimeRaw.indexOf('T') > -1) ? acceptTimeRaw : acceptTimeRaw.replace(' ', 'T')
      const parsed = new Date(normalized)
      const parsedMs = parsed.getTime()
      if (parsedMs == parsedMs) {
        eventTimeToStore = parsed.toISOString()
      }
    }

    const eventRes = await supa.from('platform_express_tracking_events').insert({
      waybill_id: final_id,
      carrier: carrier,
      tracking_no: tracking_no,
      event_time: eventTimeToStore,
      event_code: yto_status,
      event_text: event_text,
      status_code: status_code,
      raw_payload: payload,
      dedupe_key: 'WEBHOOK_' + Date.now()
    }).execute()

    if (eventRes.error != null) {
      console.error('Insert Event Error:', eventRes.error)
    }

    return true
  }

  async getMockWebhookLogs(): Promise<MockWebhookLog[]> {
    const { data } = await supa.from('platform_express_event_raw')
      .select('*')
      .order('received_at', { ascending: false })
      .limit(20)
      .execute()

    if (data == null) return []
    const list = data as Array<UTSJSONObject>
    return list.map((item: UTSJSONObject): MockWebhookLog => {
      const body = item['body'] as UTSJSONObject
      return {
        time: this.formatDBTime(item['received_at'] as string).split(' ')[1],
        carrier: item['carrier'] as string || 'Unknown',
        tracking_no: item['tracking_no'] as string || '-',
        event_code: body['infoContent'] as string || 'Raw',
        success: true,
        result_text: '接收成功',
        payload: body
      } as MockWebhookLog
    })
  }

  async syncFromCloud(id: string): Promise<boolean> {
    return new Promise((resolve) => {
      setTimeout(() => resolve(true), 500)
    })
  }

  private maskPhone(phone: string): string {
    if (!phone) return ''
    if (phone.length < 7) return phone
    return phone.substring(0, 3) + "****" + phone.substring(phone.length - 4)
  }

  private formatDBTime(iso: string): string {
    if (!iso) return ''
    const d = new Date(iso)
    const Y = d.getFullYear()
    const M = (d.getMonth() + 1).toString().padStart(2, '0')
    const D = d.getDate().toString().padStart(2, '0')
    const h = d.getHours().toString().padStart(2, '0')
    const m = d.getMinutes().toString().padStart(2, '0')
    return `${Y}-${M}-${D} ${h}:${m}`
  }

  /**
   * 统一的状态文本转换工具
   */
  public getStatusText(status: string): string {
    const text = LogisticsConstants.STATUS_MAP[status] as string | null
    return (text != null) ? text : status
  }

  /**
   * 依照需求文档：展示第三方回传的原始轨迹文案
   */
  public getDisplayMessage(text: string, status: string): string {
    if (!text) return '暂无动态'
    
    // 不再进行脱敏/泛化处理，直接返回原始文案
    return text
  }

  /**
   * 统一的状态图标转换工具
   */
  public getStatusIcon(status: string): string {
    const icon = LogisticsConstants.STATUS_ICONS[status] as string | null
    return (icon != null) ? icon : '📦'
  }
}

export const mockService = new MockService()
