import MockAdapter from 'axios-mock-adapter'
import Mock from 'mockjs'
import service from '@/utils/request'
import {
  mockCategories,
  mockProducts,
  mockUsers,
  mockOrders,
  mockCoupons,
  mockNotices,
  mockSeckillActivities,
  mockChatSessions
} from './data'

const mock = new MockAdapter(service, { delayResponse: 300 })

/**
 * 统一成功响应
 */
const ok = (data: unknown): [number, { code: number; message: string; data: unknown }] => [
  200,
  { code: 200, message: '操作成功', data }
]

const fail = (code: number, message: string): [number, { code: number; message: string; data: null }] => [
  200,
  { code, message, data: null }
]

// ============================================================
// 鉴权相关接口（login / logout / info）由真实后端处理
// Mock 不拦截，让请求走 vite proxy → server-snack
// ============================================================
mock.onPost('/api/admin/login').passThrough()
mock.onPost('/api/admin/logout').passThrough()
mock.onGet('/api/admin/info').passThrough()

/** 仪表盘（由真实后端提供） */
mock.onGet('/api/admin/dashboard/stats').passThrough()
mock.onGet(/\/api\/admin\/dashboard\/sales-trend/).passThrough()
mock.onGet('/api/admin/dashboard/order-status').passThrough()
mock.onGet('/api/admin/dashboard/hot-products').passThrough()

/** 通用分页 */
function paginate<T>(list: T[], current = 1, size = 10) {
  const total = list.length
  const pages = Math.ceil(total / size)
  const records = list.slice((current - 1) * size, current * size)
  return { records, total, size, current, pages }
}

/** 商品分类（树形） */
mock.onGet('/api/admin/category/tree').reply(() => {
  // 把扁平列表按 parentId 装配成树
  const byId = new Map<number, any>()
  mockCategories.forEach((c: any) => byId.set(c.id, { ...c, children: [] }))
  const roots: any[] = []
  byId.forEach((node) => {
    if (node.parentId === 0 || !byId.has(node.parentId)) {
      roots.push(node)
    } else {
      byId.get(node.parentId).children.push(node)
    }
  })
  return ok(roots)
})
mock.onGet('/api/admin/category/options').reply(() =>
  ok(mockCategories.map((c: any) => ({ id: c.id, name: c.name, level: c.level, parentId: c.parentId })))
)
mock.onGet(/\/api\/admin\/category\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = (mockCategories as any[]).find((c) => c.id === id)
  return found ? ok(found) : fail(404, '分类不存在')
})
mock.onPost('/api/admin/category').reply(() => ok(Date.now()))
mock.onPut('/api/admin/category').reply(() => ok(null))
mock.onDelete(/\/api\/admin\/category\/\d+$/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/category\/\d+\/status\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/category\/\d+\/sort\/\d+/).reply(() => ok(null))

/** 商品分页 */
mock.onGet('/api/admin/product/page').reply((config) => {
  const params = config.params || {}
  let rows = [...(mockProducts as any[])]
  if (params.keyword) {
    const kw = String(params.keyword).toLowerCase()
    rows = rows.filter(
      (p) =>
        (p.name || '').toLowerCase().includes(kw) ||
        (p.brand || '').toLowerCase().includes(kw)
    )
  }
  if (params.categoryId !== undefined && params.categoryId !== null && params.categoryId !== '') {
    rows = rows.filter((p) => p.categoryId === Number(params.categoryId))
  }
  if (params.status !== undefined && params.status !== null && params.status !== '') {
    rows = rows.filter((p) => p.status === Number(params.status))
  }
  if (params.isHot !== undefined && params.isHot !== null && params.isHot !== '') {
    rows = rows.filter((p) => p.isHot === Number(params.isHot))
  }
  if (params.isNew !== undefined && params.isNew !== null && params.isNew !== '') {
    rows = rows.filter((p) => p.isNew === Number(params.isNew))
  }
  // 排序
  switch (params.orderBy) {
    case 'sales_desc':
      rows.sort((a, b) => (b.sales ?? 0) - (a.sales ?? 0))
      break
    case 'price_asc':
      rows.sort((a, b) => (a.minPrice ?? 0) - (b.minPrice ?? 0))
      break
    case 'price_desc':
      rows.sort((a, b) => (b.minPrice ?? 0) - (a.minPrice ?? 0))
      break
    case 'create_desc':
    default:
      rows.sort((a, b) => (b.id ?? 0) - (a.id ?? 0))
  }
  return ok(paginate(rows, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/product\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = (mockProducts as any[]).find((p) => p.id === id)
  if (!found) return fail(404, '商品不存在')
  return ok({
    ...found,
    subImages: [],
    detail: '<p>富文本详情（mock）</p>',
    originPrice: found.minPrice ? found.minPrice * 1.2 : 0,
    viewCount: 0,
    skuList: [
      {
        id: found.id * 100 + 1,
        productId: found.id,
        skuName: '原味/500g',
        image: found.mainImage,
        price: found.minPrice ?? 0,
        stock: found.totalStock ?? 0,
        sales: found.sales ?? 0,
        weight: 500,
        sort: 1
      }
    ]
  })
})
mock.onPost('/api/admin/product').reply(() => ok(Date.now()))
mock.onPut('/api/admin/product').reply(() => ok(null))
mock.onDelete(/\/api\/admin\/product\/\d+$/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/product\/\d+\/status\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/product\/\d+\/hot\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/product\/\d+\/new\/\d+/).reply(() => ok(null))
mock.onPut('/api/admin/product/stock/adjust').reply(() => ok(null))

/** 用户分页 */
mock.onGet('/api/admin/user/page').reply((config) => {
  const params = config.params || {}
  let rows = [...(mockUsers as any[])]
  if (params.keyword) {
    const kw = String(params.keyword).toLowerCase()
    rows = rows.filter(
      (u) =>
        (u.username || '').toLowerCase().includes(kw) ||
        (u.phone || '').toLowerCase().includes(kw)
    )
  }
  if (params.status !== undefined && params.status !== null && params.status !== '') {
    rows = rows.filter((u) => u.status === Number(params.status))
  }
  return ok(paginate(rows, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/user\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = (mockUsers as any[]).find((u) => u.id === id)
  return found ? ok(found) : fail(404, '用户不存在')
})
mock.onPost('/api/admin/user').reply(() => ok(Date.now()))
mock.onPut('/api/admin/user').reply(() => ok(null))
mock.onDelete(/\/api\/admin\/user\/\d+$/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/user\/\d+\/status\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/user\/\d+\/password\/reset/).reply(() => ok(null))
mock.onGet(/\/api\/admin\/user\/\d+\/orders/).reply((config) => {
  // 随机给几条假订单
  const list = [
    {
      id: 1001, orderNo: 'SN202605200001', userId: 1,
      totalAmount: 99, freightAmount: 0, discountAmount: 0, couponAmount: 0, payAmount: 99,
      status: 3, statusText: '已完成', statusTagType: 'success',
      receiverName: '小张', receiverPhone: '13800138001', receiverAddress: '北京市朝阳区xx路',
      trackingCompany: '顺丰', trackingNo: 'SF1234567890',
      payTime: '2026-05-20 10:00:00', deliverTime: '2026-05-21 14:00:00', receiveTime: '2026-05-23 18:00:00',
      createTime: '2026-05-20 09:55:00', payChannel: 'alipay', payChannelText: '支付宝'
    },
    {
      id: 1002, orderNo: 'SN202605100002', userId: 1,
      totalAmount: 49, freightAmount: 8, discountAmount: 0, couponAmount: 5, payAmount: 52,
      status: 2, statusText: '待收货', statusTagType: 'success',
      receiverName: '小张', receiverPhone: '13800138001', receiverAddress: '北京市朝阳区xx路',
      trackingCompany: '圆通', trackingNo: 'YT9876543210',
      payTime: '2026-05-10 12:00:00', deliverTime: '2026-05-11 09:00:00', receiveTime: '',
      createTime: '2026-05-10 11:50:00', payChannel: 'wechat', payChannelText: '微信'
    },
    {
      id: 1003, orderNo: 'SN202604150003', userId: 1,
      totalAmount: 128, freightAmount: 0, discountAmount: 0, couponAmount: 0, payAmount: 128,
      status: 0, statusText: '待付款', statusTagType: 'warning',
      receiverName: '小张', receiverPhone: '13800138001', receiverAddress: '北京市朝阳区xx路',
      trackingCompany: '', trackingNo: '',
      payTime: '', deliverTime: '', receiveTime: '',
      createTime: '2026-04-15 15:30:00', payChannel: '', payChannelText: ''
    }
  ]
  const params = config.params || {}
  return ok(paginate(list, params.current || 1, params.size || 10))
})

/** 管理员（后台账号） */
const mockAdmins = [
  {
    id: 1, username: 'admin', nickname: '超级管理员', avatar: '', email: 'admin@snack.com',
    phone: '13800138000', role: 'super_admin', status: 1,
    lastLoginTime: '2026-06-02 22:30:00', lastLoginIp: '127.0.0.1',
    createTime: '2026-01-01 00:00:00'
  },
  {
    id: 2, username: 'manager', nickname: '运营经理', avatar: '', email: 'manager@snack.com',
    phone: '13800138001', role: 'admin', status: 1,
    lastLoginTime: '2026-06-01 18:00:00', lastLoginIp: '127.0.0.1',
    createTime: '2026-01-15 10:00:00'
  },
  {
    id: 3, username: 'operator', nickname: '客服小王', avatar: '', email: 'op@snack.com',
    phone: '13800138002', role: 'operator', status: 1,
    lastLoginTime: '2026-05-30 09:30:00', lastLoginIp: '127.0.0.1',
    createTime: '2026-02-01 12:00:00'
  },
  {
    id: 4, username: 'frozen', nickname: '已停用账号', avatar: '', email: '',
    phone: '', role: 'operator', status: 0,
    lastLoginTime: '', lastLoginIp: '',
    createTime: '2026-03-01 00:00:00'
  }
] as any[]

mock.onGet('/api/admin/page').reply((config) => {
  const params = config.params || {}
  let rows = [...mockAdmins]
  if (params.keyword) {
    const kw = String(params.keyword).toLowerCase()
    rows = rows.filter(
      (a) =>
        a.username.toLowerCase().includes(kw) ||
        (a.nickname || '').toLowerCase().includes(kw) ||
        (a.phone || '').toLowerCase().includes(kw)
    )
  }
  if (params.role) rows = rows.filter((a) => a.role === params.role)
  if (params.status !== undefined && params.status !== null && params.status !== '') {
    rows = rows.filter((a) => a.status === Number(params.status))
  }
  return ok(paginate(rows, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = mockAdmins.find((a) => a.id === id)
  return found ? ok(found) : fail(404, '管理员不存在')
})
mock.onPost('/api/admin').reply(() => ok(Date.now()))
mock.onPut('/api/admin').reply(() => ok(null))
mock.onDelete(/\/api\/admin\/\d+$/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/\d+\/status\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/\d+\/password\/reset/).reply(() => ok(null))

/** 订单分页 */
mock.onGet('/api/admin/order/page').reply((config) => {
  const params = config.params || {}
  return ok(paginate(mockOrders, params.current || 1, params.size || 10))
})
mock.onPut(/\/api\/admin\/order\/\d+\/(deliver|cancel)/).reply(() => ok(null))

/** 优惠券 */
mock.onGet('/api/admin/coupon/page').reply((config) => {
  const params = config.params || {}
  let rows = [...(mockCoupons as any[])]
  if (params.keyword) {
    const kw = String(params.keyword).toLowerCase()
    rows = rows.filter((c) => (c.name || '').toLowerCase().includes(kw))
  }
  if (params.type !== undefined && params.type !== null && params.type !== '') {
    rows = rows.filter((c) => Number(c.type) === Number(params.type))
  }
  if (params.status !== undefined && params.status !== null && params.status !== '') {
    rows = rows.filter((c) => Number(c.status) === Number(params.status))
  }
  return ok(paginate(rows, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/coupon\/\d+$/).reply((config) => {
  const id = Number(config.url?.match(/\/coupon\/(\d+)/)?.[1])
  return ok((mockCoupons as any[]).find((c) => c.id === id) || null)
})
mock.onPost('/api/admin/coupon').reply(() => ok(1))
mock.onPut('/api/admin/coupon').reply(() => ok(null))
mock.onDelete(/\/api\/admin\/coupon\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/coupon\/\d+\/status/).reply(() => ok(null))
mock.onGet(/\/api\/admin\/coupon(\/\d+)?\/records|\/api\/admin\/coupon\/record\/page/).reply((config) => {
  const params = config.params || {}
  const couponId = Number(config.url?.match(/\/coupon\/(\d+)\/records/)?.[1] || params.couponId || 1)
  const records = Array.from({ length: 24 }).map((_, i) => {
    const user = (mockUsers as any[])[i % (mockUsers as any[]).length]
    const coupon = (mockCoupons as any[]).find((c) => c.id === couponId) || (mockCoupons as any[])[0]
    return {
      id: i + 1,
      userId: user.id,
      username: user.username,
      nickname: user.nickname,
      couponId: coupon.id,
      couponName: coupon.name,
      couponType: coupon.type,
      status: i % 4,
      orderId: i % 4 === 1 ? 1000 + i : null,
      receiveTime: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss'),
      useTime: i % 4 === 1 ? Mock.Random.datetime('yyyy-MM-dd HH:mm:ss') : null,
      expireTime: Mock.Random.datetime('yyyy-MM-dd HH:mm:ss')
    }
  })
  let rows = records
  if (params.status !== undefined && params.status !== null && params.status !== '') {
    rows = rows.filter((r) => Number(r.status) === Number(params.status))
  }
  if (params.keyword) {
    const kw = String(params.keyword).toLowerCase()
    rows = rows.filter((r) =>
      [r.username, r.nickname].some((v) => String(v || '').toLowerCase().includes(kw))
    )
  }
  return ok(paginate(rows, params.current || 1, params.size || 10))
})

/** 公告 */
mock.onGet('/api/admin/notice/page').reply((config) => {
  const params = config.params || {}
  let rows = [...(mockNotices as any[])]
  if (params.keyword) {
    const kw = String(params.keyword).toLowerCase()
    rows = rows.filter((n) => (n.title || '').toLowerCase().includes(kw))
  }
  if (params.type !== undefined && params.type !== null && params.type !== '') {
    rows = rows.filter((n) => n.type === Number(params.type))
  }
  if (params.status !== undefined && params.status !== null && params.status !== '') {
    rows = rows.filter((n) => n.status === Number(params.status))
  }
  return ok(paginate(rows, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/notice\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = (mockNotices as any[]).find((n) => n.id === id)
  return found ? ok(found) : fail(404, '公告不存在')
})
mock.onPost('/api/admin/notice').reply(() => ok(Date.now()))
mock.onPut('/api/admin/notice').reply(() => ok(null))
mock.onDelete(/\/api\/admin\/notice\/\d+$/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/notice\/\d+\/status\/\d+/).reply(() => ok(null))
mock.onPut(/\/api\/admin\/notice\/\d+\/top\/\d+/).reply(() => ok(null))

/** 抢购 */
const mockSeckillList = [...mockSeckillActivities] as any[]
const mockSeckillProducts = new Map<number, any[]>()
let seckillProductSeq = 1000

;(mockSeckillActivities as any[]).forEach((activity, index) => {
  const product = (mockProducts as any[])[index % mockProducts.length]
  if (!product) return
  mockSeckillProducts.set(activity.id, [
    {
      id: ++seckillProductSeq,
      activityId: activity.id,
      productId: product.id,
      productName: product.name,
      productImage: product.mainImage,
      skuId: product.id * 100 + 1,
      skuName: '原味/500g',
      originPrice: Number((product.minPrice * 1.2).toFixed(2)),
      seckillPrice: Number((product.minPrice * 0.8).toFixed(2)),
      discount: 8,
      seckillStock: 100,
      remainStock: 60,
      soldPercent: 40,
      perLimit: 1,
      sort: 1,
      sales: 40
    }
  ])
})

mock.onGet('/api/admin/seckill/page').reply((config) => {
  const params = config.params || {}
  return ok(paginate(mockSeckillList, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/seckill\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = mockSeckillList.find((a) => a.id === id)
  if (!found) return fail(404, '活动不存在')
  return ok({ ...found, products: mockSeckillProducts.get(id) ?? [] })
})
mock.onPost('/api/admin/seckill').reply((config) => {
  const body = JSON.parse(config.data || '{}')
  const id = mockSeckillList.reduce((max: number, a: any) => Math.max(max, a.id), 0) + 1
  mockSeckillList.unshift({
    id,
    name: body.name,
    startTime: body.startTime,
    endTime: body.endTime,
    status: 0,
    createTime: new Date().toISOString().replace('T', ' ').slice(0, 19)
  })
  return ok(id)
})
mock.onPut('/api/admin/seckill').reply((config) => {
  const body = JSON.parse(config.data || '{}')
  const found = mockSeckillList.find((a) => a.id === body.id)
  if (found) Object.assign(found, body)
  return ok(null)
})
mock.onDelete(/\/api\/admin\/seckill\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const index = mockSeckillList.findIndex((a) => a.id === id)
  if (index >= 0) mockSeckillList.splice(index, 1)
  mockSeckillProducts.delete(id)
  return ok(null)
})
mock.onPut(/\/api\/admin\/seckill\/\d+\/end/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  const found = mockSeckillList.find((a) => a.id === id)
  if (found) found.status = 2
  return ok(null)
})
mock.onPost(/\/api\/admin\/seckill\/\d+\/warmup/).reply(() => ok(null))
mock.onPost('/api/admin/seckill/product').reply((config) => {
  const body = JSON.parse(config.data || '{}')
  const skuId = Number(body.skuId)
  const productId = Number(body.productId ?? Math.floor(skuId / 100))
  const product = (mockProducts as any[]).find((p) => p.id === productId)
  const originPrice = Number(body.originPrice ?? product?.minPrice ?? 0)
  const seckillPrice = Number(body.seckillPrice ?? 0)
  const item = {
    id: ++seckillProductSeq,
    activityId: Number(body.activityId),
    productId,
    productName: product?.name ?? '抢购商品',
    productImage: product?.mainImage ?? '',
    skuId,
    skuName: '原味/500g',
    originPrice,
    seckillPrice,
    discount: originPrice > 0 ? Number((seckillPrice / originPrice * 10).toFixed(1)) : 0,
    seckillStock: Number(body.seckillStock ?? 0),
    remainStock: Number(body.seckillStock ?? 0),
    soldPercent: 0,
    perLimit: Number(body.perLimit ?? 1),
    sort: Number(body.sort ?? 0),
    sales: 0
  }
  const list = mockSeckillProducts.get(item.activityId) ?? []
  list.push(item)
  mockSeckillProducts.set(item.activityId, list)
  return ok(item.id)
})
mock.onDelete(/\/api\/admin\/seckill\/product\/\d+$/).reply((config) => {
  const id = Number(config.url!.split('/').pop())
  mockSeckillProducts.forEach((list) => {
    const index = list.findIndex((p) => p.id === id)
    if (index >= 0) list.splice(index, 1)
  })
  return ok(null)
})

/** 客服 */
mock.onGet('/api/admin/chat/session/page').reply((config) => {
  const params = config.params || {}
  return ok(paginate(mockChatSessions, params.current || 1, params.size || 10))
})
mock.onGet(/\/api\/admin\/chat\/session\/\d+\/messages/).reply(() =>
  ok([
    { id: 1, sessionId: 1, senderType: 0, type: 'text', content: '你好，请问夏威夷果还有货吗？', createTime: '2026-06-01 14:00:00' },
    { id: 2, sessionId: 1, senderType: 1, type: 'text', content: '亲，在的哦，目前库存充足~', createTime: '2026-06-01 14:01:00' }
  ])
)
mock.onPost(/\/api\/admin\/chat\/session\/\d+\/message/).reply(() => ok(null))

console.log('[Mock] 接口拦截已启用 ✓')
export default mock
