import { ref, computed } from 'vue'
import {
  createInitialIotState,
  SENSOR_STATUS,
  COLLECTION_STATUS,
  PROCESSING_STATUS,
  ALERT_LEVEL,
  ALERT_STATUS,
  SENSOR_TYPES,
} from '../mocks/iotMonitoringMockData.js'

const STORAGE_KEY = 'dockscope_iot_monitoring_v1'

function loadState() {
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    if (raw) return JSON.parse(raw)
  } catch (e) {
    console.warn('【IoT 数据】读取 localStorage 失败，使用种子数据', e)
  }
  return createInitialIotState()
}

function saveState(state) {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(state))
}

const state = ref(loadState())
const loading = ref(false)

function persist() {
  saveState(state.value)
}

function sensorById(id) {
  return state.value.sensors.find((s) => s.sensor_id === id)
}

function taskById(id) {
  return state.value.collectionTasks.find((t) => t.task_id === id)
}

function enrichTask(task) {
  const sensor = sensorById(task.sensor_id)
  return {
    ...task,
    sensor_name: sensor?.name ?? '—',
    sensor_code: sensor?.sensor_code ?? '—',
    bridge_section: sensor?.bridge_section ?? '—',
  }
}

function enrichJob(job) {
  const task = taskById(job.source_task_id)
  return {
    ...job,
    source_task_name: task?.task_name ?? '—',
  }
}

function enrichAlert(alert) {
  const sensor = sensorById(alert.sensor_id)
  return {
    ...alert,
    sensor_name: sensor?.name ?? '—',
    sensor_code: sensor?.sensor_code ?? '—',
  }
}

function nextId(key) {
  const id = state.value.nextIds[key]
  state.value.nextIds[key] = id + 1
  return id
}

function pushAlert({ sensor_id, level, title, message, trigger_value, threshold_value }) {
  const t = new Date().toISOString()
  state.value.alerts.unshift({
    alert_id: nextId('alert'),
    sensor_id,
    level,
    title,
    message,
    status: ALERT_STATUS.OPEN,
    trigger_value: trigger_value ?? null,
    threshold_value: threshold_value ?? null,
    created_at: t,
    acknowledged_at: null,
    resolved_at: null,
  })
}

export function useIotMonitoringStore() {
  const sensors = computed(() => state.value.sensors)
  const collectionTasks = computed(() => state.value.collectionTasks.map(enrichTask))
  const processingJobs = computed(() => state.value.processingJobs.map(enrichJob))
  const alerts = computed(() => state.value.alerts.map(enrichAlert))

  const onlineSensorCount = computed(
    () => state.value.sensors.filter((s) => s.status === SENSOR_STATUS.ONLINE).length,
  )
  const runningTaskCount = computed(
    () => state.value.collectionTasks.filter((t) => t.status === COLLECTION_STATUS.RUNNING).length,
  )
  const openAlertCount = computed(
    () => state.value.alerts.filter((a) => a.status === ALERT_STATUS.OPEN).length,
  )

  function resetToSeed() {
    state.value = createInitialIotState()
    persist()
  }

  function listSensors(filters = {}) {
    let list = [...state.value.sensors]
    const { keyword, status, sensor_type } = filters
    if (keyword) {
      const k = keyword.toLowerCase()
      list = list.filter(
        (s) =>
          s.sensor_code.toLowerCase().includes(k) ||
          s.name.toLowerCase().includes(k) ||
          s.bridge_section.toLowerCase().includes(k),
      )
    }
    if (status) list = list.filter((s) => s.status === status)
    if (sensor_type) list = list.filter((s) => s.sensor_type === sensor_type)
    return list
  }

  function upsertSensor(payload) {
    const t = new Date().toISOString()
    if (payload.sensor_id) {
      const idx = state.value.sensors.findIndex((s) => s.sensor_id === payload.sensor_id)
      if (idx === -1) return { ok: false, message: '传感器不存在' }
      state.value.sensors[idx] = { ...state.value.sensors[idx], ...payload, updated_at: t }
      persist()
      return { ok: true, sensor: state.value.sensors[idx] }
    }
    const sensor = {
      sensor_id: nextId('sensor'),
      sensor_code: payload.sensor_code,
      name: payload.name,
      bridge_section: payload.bridge_section,
      sensor_type: payload.sensor_type,
      status: payload.status || SENSOR_STATUS.OFFLINE,
      install_location: payload.install_location || '',
      sampling_hz: Number(payload.sampling_hz) || 10,
      threshold_max: Number(payload.threshold_max) ?? 100,
      threshold_min: Number(payload.threshold_min) ?? 0,
      last_heartbeat: payload.status === SENSOR_STATUS.ONLINE ? t : null,
      firmware_version: payload.firmware_version || 'v1.0.0',
      remark: payload.remark || '',
      created_at: t,
      updated_at: t,
    }
    state.value.sensors.push(sensor)
    persist()
    return { ok: true, sensor }
  }

  function deleteSensor(sensorId) {
    const used = state.value.collectionTasks.some((t) => t.sensor_id === sensorId)
    if (used) return { ok: false, message: '该传感器仍有关联采集任务，请先删除或改绑任务' }
    state.value.sensors = state.value.sensors.filter((s) => s.sensor_id !== sensorId)
    state.value.alerts = state.value.alerts.filter((a) => a.sensor_id !== sensorId)
    persist()
    return { ok: true }
  }

  function toggleSensorStatus(sensorId) {
    const sensor = sensorById(sensorId)
    if (!sensor) return { ok: false, message: '传感器不存在' }
    const t = new Date().toISOString()
    if (sensor.status === SENSOR_STATUS.ONLINE) {
      sensor.status = SENSOR_STATUS.OFFLINE
      pushAlert({
        sensor_id: sensorId,
        level: ALERT_LEVEL.WARNING,
        title: '传感器手动下线',
        message: `${sensor.name} 已被设为离线，关联采集任务将暂停。`,
      })
      state.value.collectionTasks
        .filter((task) => task.sensor_id === sensorId && task.status === COLLECTION_STATUS.RUNNING)
        .forEach((task) => {
          task.status = COLLECTION_STATUS.PAUSED
          task.updated_at = t
        })
    } else {
      sensor.status = SENSOR_STATUS.ONLINE
      sensor.last_heartbeat = t
    }
    sensor.updated_at = t
    persist()
    return { ok: true, sensor }
  }

  function simulateHeartbeat(sensorId) {
    const sensor = sensorById(sensorId)
    if (!sensor) return { ok: false, message: '传感器不存在' }
    const t = new Date().toISOString()
    sensor.last_heartbeat = t
    if (sensor.status !== SENSOR_STATUS.MAINTENANCE) {
      sensor.status = SENSOR_STATUS.ONLINE
    }
    sensor.updated_at = t
    persist()
    return { ok: true, sensor }
  }

  function listCollectionTasks(filters = {}) {
    let list = state.value.collectionTasks.map(enrichTask)
    const { keyword, status, sensor_id } = filters
    if (keyword) {
      const k = keyword.toLowerCase()
      list = list.filter(
        (t) =>
          t.task_name.toLowerCase().includes(k) ||
          t.sensor_name.toLowerCase().includes(k) ||
          String(t.task_id).includes(k),
      )
    }
    if (status) list = list.filter((t) => t.status === status)
    if (sensor_id) list = list.filter((t) => t.sensor_id === sensor_id)
    return list
  }

  function upsertCollectionTask(payload) {
    const sensor = sensorById(payload.sensor_id)
    if (!sensor) return { ok: false, message: '请选择有效传感器' }
    const t = new Date().toISOString()
    if (payload.task_id) {
      const idx = state.value.collectionTasks.findIndex((x) => x.task_id === payload.task_id)
      if (idx === -1) return { ok: false, message: '采集任务不存在' }
      state.value.collectionTasks[idx] = {
        ...state.value.collectionTasks[idx],
        ...payload,
        updated_at: t,
      }
      persist()
      return { ok: true, task: enrichTask(state.value.collectionTasks[idx]) }
    }
    const task = {
      task_id: nextId('task'),
      task_name: payload.task_name,
      sensor_id: payload.sensor_id,
      interval_sec: Number(payload.interval_sec) || 60,
      batch_size: Number(payload.batch_size) || 100,
      status: COLLECTION_STATUS.IDLE,
      last_run_at: null,
      sample_count: 0,
      error_message: '',
      created_at: t,
      updated_at: t,
    }
    state.value.collectionTasks.push(task)
    persist()
    return { ok: true, task: enrichTask(task) }
  }

  function deleteCollectionTask(taskId) {
    const linked = state.value.processingJobs.some((j) => j.source_task_id === taskId)
    if (linked) return { ok: false, message: '该任务已有数据处理作业，无法删除' }
    state.value.collectionTasks = state.value.collectionTasks.filter((t) => t.task_id !== taskId)
    persist()
    return { ok: true }
  }

  function startCollection(taskId) {
    const task = taskById(taskId)
    if (!task) return { ok: false, message: '任务不存在' }
    const sensor = sensorById(task.sensor_id)
    if (!sensor || sensor.status !== SENSOR_STATUS.ONLINE) {
      return { ok: false, message: '关联传感器未在线，无法启动采集' }
    }
    const t = new Date().toISOString()
    task.status = COLLECTION_STATUS.RUNNING
    task.last_run_at = t
    task.error_message = ''
    task.updated_at = t
    persist()
    return { ok: true, task: enrichTask(task) }
  }

  function pauseCollection(taskId) {
    const task = taskById(taskId)
    if (!task) return { ok: false, message: '任务不存在' }
    const t = new Date().toISOString()
    task.status = COLLECTION_STATUS.PAUSED
    task.updated_at = t
    persist()
    return { ok: true, task: enrichTask(task) }
  }

  function runCollectionOnce(taskId) {
    const task = taskById(taskId)
    if (!task) return { ok: false, message: '任务不存在' }
    const sensor = sensorById(task.sensor_id)
    if (!sensor || sensor.status !== SENSOR_STATUS.ONLINE) {
      task.status = COLLECTION_STATUS.ERROR
      task.error_message = '传感器离线，采集失败'
      task.updated_at = new Date().toISOString()
      pushAlert({
        sensor_id: task.sensor_id,
        level: ALERT_LEVEL.CRITICAL,
        title: '采集失败',
        message: task.error_message,
      })
      persist()
      return { ok: false, message: task.error_message }
    }
    const t = new Date().toISOString()
    const added = task.batch_size
    task.sample_count += added
    task.last_run_at = t
    task.updated_at = t
    if (task.status === COLLECTION_STATUS.IDLE) task.status = COLLECTION_STATUS.PAUSED

    const mockValue =
      sensor.sensor_type === 'strain'
        ? 800 + Math.random() * 400
        : sensor.sensor_type === 'vibration'
          ? 2 + Math.random() * 5
          : 10 + Math.random() * 20

    if (mockValue > sensor.threshold_max * 0.9) {
      pushAlert({
        sensor_id: sensor.sensor_id,
        level: ALERT_LEVEL.WARNING,
        title: '监测值接近阈值',
        message: `${sensor.name} 本次采样值 ${mockValue.toFixed(2)}，已超过预警线 90%。`,
        trigger_value: Number(mockValue.toFixed(2)),
        threshold_value: sensor.threshold_max,
      })
    }
    if (mockValue > sensor.threshold_max) {
      pushAlert({
        sensor_id: sensor.sensor_id,
        level: ALERT_LEVEL.CRITICAL,
        title: '监测值超阈值',
        message: `${sensor.name} 本次采样值 ${mockValue.toFixed(2)}，已超过上限 ${sensor.threshold_max}。`,
        trigger_value: Number(mockValue.toFixed(2)),
        threshold_value: sensor.threshold_max,
      })
    }
    persist()
    return { ok: true, task: enrichTask(task), added }
  }

  function listProcessingJobs(filters = {}) {
    let list = state.value.processingJobs.map(enrichJob)
    const { keyword, status } = filters
    if (keyword) {
      const k = keyword.toLowerCase()
      list = list.filter(
        (j) => j.job_name.toLowerCase().includes(k) || j.pipeline.toLowerCase().includes(k),
      )
    }
    if (status) list = list.filter((j) => j.status === status)
    return list
  }

  function createProcessingJob(payload) {
    const task = taskById(payload.source_task_id)
    if (!task) return { ok: false, message: '请选择有效采集任务' }
    if (task.sample_count < 1) return { ok: false, message: '采集任务尚无样本，请先执行采集' }
    const t = new Date().toISOString()
    const job = {
      job_id: nextId('job'),
      job_name: payload.job_name,
      source_task_id: payload.source_task_id,
      pipeline: payload.pipeline || 'clean → aggregate → export',
      status: PROCESSING_STATUS.PENDING,
      progress: 0,
      input_records: task.sample_count,
      output_records: 0,
      started_at: null,
      finished_at: null,
      created_at: t,
      updated_at: t,
    }
    state.value.processingJobs.unshift(job)
    persist()
    return { ok: true, job: enrichJob(job) }
  }

  function startProcessing(jobId) {
    const job = state.value.processingJobs.find((j) => j.job_id === jobId)
    if (!job) return { ok: false, message: '作业不存在' }
    if (job.status === PROCESSING_STATUS.RUNNING) return { ok: false, message: '作业已在运行中' }
    const t = new Date().toISOString()
    job.status = PROCESSING_STATUS.RUNNING
    job.started_at = t
    job.progress = 5
    job.updated_at = t
    persist()
    return { ok: true, job: enrichJob(job) }
  }

  function advanceProcessing(jobId) {
    const job = state.value.processingJobs.find((j) => j.job_id === jobId)
    if (!job || job.status !== PROCESSING_STATUS.RUNNING) {
      return { ok: false, message: '作业未在运行' }
    }
    const t = new Date().toISOString()
    job.progress = Math.min(100, job.progress + 25)
    job.output_records = Math.floor((job.input_records * job.progress) / 100)
    job.updated_at = t
    if (job.progress >= 100) {
      job.status = PROCESSING_STATUS.COMPLETED
      job.finished_at = t
    }
    persist()
    return { ok: true, job: enrichJob(job) }
  }

  function deleteProcessingJob(jobId) {
    const job = state.value.processingJobs.find((j) => j.job_id === jobId)
    if (job?.status === PROCESSING_STATUS.RUNNING) {
      return { ok: false, message: '运行中的作业无法删除' }
    }
    state.value.processingJobs = state.value.processingJobs.filter((j) => j.job_id !== jobId)
    persist()
    return { ok: true }
  }

  function listAlerts(filters = {}) {
    let list = state.value.alerts.map(enrichAlert)
    const { keyword, status, level, sensor_id } = filters
    if (keyword) {
      const k = keyword.toLowerCase()
      list = list.filter(
        (a) =>
          a.title.toLowerCase().includes(k) ||
          a.message.toLowerCase().includes(k) ||
          a.sensor_name.toLowerCase().includes(k),
      )
    }
    if (status) list = list.filter((a) => a.status === status)
    if (level) list = list.filter((a) => a.level === level)
    if (sensor_id) list = list.filter((a) => a.sensor_id === sensor_id)
    return list.sort((a, b) => new Date(b.created_at) - new Date(a.created_at))
  }

  function acknowledgeAlert(alertId) {
    const alert = state.value.alerts.find((a) => a.alert_id === alertId)
    if (!alert) return { ok: false, message: '预警不存在' }
    if (alert.status === ALERT_STATUS.RESOLVED) {
      return { ok: false, message: '已关闭的预警无法确认' }
    }
    alert.status = ALERT_STATUS.ACKNOWLEDGED
    alert.acknowledged_at = new Date().toISOString()
    persist()
    return { ok: true, alert: enrichAlert(alert) }
  }

  function resolveAlert(alertId) {
    const alert = state.value.alerts.find((a) => a.alert_id === alertId)
    if (!alert) return { ok: false, message: '预警不存在' }
    const t = new Date().toISOString()
    alert.status = ALERT_STATUS.RESOLVED
    alert.resolved_at = t
    if (!alert.acknowledged_at) alert.acknowledged_at = t
    persist()
    return { ok: true, alert: enrichAlert(alert) }
  }

  function getSensorTypeLabel(value) {
    return SENSOR_TYPES.find((t) => t.value === value)?.label ?? value
  }

  return {
    loading,
    sensors,
    collectionTasks,
    processingJobs,
    alerts,
    onlineSensorCount,
    runningTaskCount,
    openAlertCount,
    SENSOR_STATUS,
    COLLECTION_STATUS,
    PROCESSING_STATUS,
    ALERT_LEVEL,
    ALERT_STATUS,
    SENSOR_TYPES,
    resetToSeed,
    listSensors,
    upsertSensor,
    deleteSensor,
    toggleSensorStatus,
    simulateHeartbeat,
    listCollectionTasks,
    upsertCollectionTask,
    deleteCollectionTask,
    startCollection,
    pauseCollection,
    runCollectionOnce,
    listProcessingJobs,
    createProcessingJob,
    startProcessing,
    advanceProcessing,
    deleteProcessingJob,
    listAlerts,
    acknowledgeAlert,
    resolveAlert,
    getSensorTypeLabel,
    sensorById,
    taskById,
  }
}
