import { normalizeResponseData, requestJson } from "./request"

const JSY_API_BASE = import.meta.env.VITE_JSY_API_BASE || "/jsyApi"
const EZVIZ_ACCESS_TOKEN = String(import.meta.env.VITE_EZVIZ_ACCESS_TOKEN || "").trim()
const HONGYUAN_TOWN_NAMES = [
  "邛溪镇",
  "刷经寺镇",
  "安曲镇",
  "龙日镇",
  "江茸乡",
  "查尔玛乡",
  "瓦切镇",
  "阿木乡",
  "麦洼乡",
  "色地镇",
]

function joinBase(path) {
  if (/^https?:\/\//.test(path)) return path
  return `${JSY_API_BASE}${path.startsWith("/") ? path : `/${path}`}`
}

function unwrapResponse(response) {
  const failed =
    response?.success === false ||
    (response?.code !== undefined && ![0, 200, "0", "200"].includes(response.code))

  if (failed) {
    const error = new Error(response?.msg || response?.message || "视频监控接口请求失败")
    error.code = response?.code
    throw error
  }

  return normalizeResponseData(response)
}

function pickValue(item, keys, fallback = "") {
  for (const key of keys) {
    if (item?.[key] !== undefined && item?.[key] !== null && item?.[key] !== "") {
      return item[key]
    }
  }
  return fallback
}

function getMonitoringToken(row) {
  return EZVIZ_ACCESS_TOKEN || pickValue(row, ["token", "accessToken", "access_token"])
}

function getMonitoringPlayUrl(row) {
  return pickValue(row, ["hdPlayUrl", "hd_play_url", "playUrl", "play_url", "url"])
}

function isMonitoringOnline(row) {
  const status = pickValue(row, [
    "isOnline",
    "online",
    "status",
    "deviceStatus",
    "statusName",
    "state",
    "onlineStatus",
    "deviceState",
  ])
  if (status === "") return true
  if (typeof status === "boolean") return status
  if (typeof status === "number") return status !== 0
  const text = String(status).trim().toLowerCase()
  if (!text) return true
  if (["1", "true", "online", "on"].includes(text)) return true
  if (["0", "false", "offline", "off"].includes(text)) return false
  if (/(离线|不在线|未在线|断线|断开|异常|故障|停用|不可用|offline|disabled|closed|stop)/i.test(text)) return false
  if (/(在线|直播中|正常|可用|online|enabled|open|running|active)/i.test(text)) return true
  return true
}

export function isPlayableMonitoring(row) {
  return Boolean(getMonitoringToken(row) && getMonitoringPlayUrl(row) && isMonitoringOnline(row))
}

function inferTownName(name = "") {
  const normalizedName = String(name)
  const town = HONGYUAN_TOWN_NAMES.find((item) => normalizedName.includes(item.replace(/[镇乡]$/, "")))
  return town || "红原县"
}

function inferSceneName(name = "") {
  const text = String(name)
  if (text.includes("养殖")) return "养殖基地"
  if (text.includes("饲草")) return "饲草基地"
  if (text.includes("种草") || text.includes("牧草")) return "牧草基地"
  if (text.includes("虫情")) return "虫情监测"
  if (text.includes("机场")) return "机场周边"
  return "重点点位"
}

function getChannel(row, index) {
  const url = pickValue(row, ["hdPlayUrl", "playUrl", "url"])
  const match = String(url).match(/\/(\d+)(?:\.hd)?\.live/i)
  if (match) return match[1].padStart(2, "0")
  return String(index + 1).padStart(2, "0")
}

function getUpdateTime() {
  return new Date().toLocaleTimeString("zh-CN", {
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
  })
}

function normalizeMonitoring(row, index, total, validTotal) {
  const name = pickValue(row, ["name", "title", "deviceName"], `视频监控${index + 1}`)
  const hdPlayUrl = pickValue(row, ["hdPlayUrl", "hd_play_url", "url"])
  const playUrl = pickValue(row, ["playUrl", "play_url"], hdPlayUrl)
  const token = getMonitoringToken(row)
  const isOnline = isPlayableMonitoring(row)
  const onlineRate = total ? Math.round((validTotal / total) * 100) : 0

  return {
    key: pickValue(row, ["id", "number", "deviceSerial"], `${name}-${index}`),
    title: name,
    town: inferTownName(name),
    scene: inferSceneName(name),
    device: pickValue(row, ["number", "deviceSerial", "serialNumber"], `CAM-${String(index + 1).padStart(3, "0")}`),
    channel: getChannel(row, index),
    cameraCount: total,
    status: isOnline ? "直播中" : "离线",
    onlineRate,
    updateTime: getUpdateTime(),
    operator: isOnline ? "萤石云 · 在线预览" : "监控参数待同步",
    progress: isOnline ? 100 : 0,
    image: pickValue(row, ["img", "image", "cover", "snapshot"]),
    playUrl,
    hdPlayUrl,
    token,
    source: row,
  }
}

export async function getHomeMonitorings(params = {}) {
  const data = await requestJson(joinBase("/api/home/monitorings"), {
    params,
    timeout: 18000,
  }).then(unwrapResponse)
  const rows = Array.isArray(data) ? data : data?.rows || data?.list || []
  const playableRows = rows.filter(isPlayableMonitoring)
  return playableRows.map((row, index) => normalizeMonitoring(row, index, rows.length, playableRows.length))
}
