<template>
  <div class="page-container">
    <!-- 搜索表单 -->
    <div class="search-form">
      <el-form :model="searchForm" inline>
        <el-form-item :label="t('Stream SN')">
          <el-input
            v-model.trim="searchForm.aoAgent"
            placeholder="请输入AO代理"
            clearable
            @keyup.enter="handleSearch"
          />
        </el-form-item>
        <el-form-item :label="t('功能')">
          <el-input v-model.trim="searchForm.feature" placeholder="请输入功能" clearable @keyup.enter="handleSearch" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch">{{ t('查询') }}</el-button>
          <el-button :icon="RefreshRight" @click="handleReset">{{ t('重置') }}</el-button>
        </el-form-item>
      </el-form>
    </div>

    <!-- 数据表格 -->
    <div class="table-wrapper">
      <el-table
        ref="tableRef"
        v-loading="loading"
        :data="streamList"
        stripe
        size="default"
        height="100%"
        @sort-change="handleSortChange"
      >
        <el-table-column prop="streamSn" :label="t('stream sn')" min-width="140" show-overflow-tooltip />
        <el-table-column prop="name" :label="t('name')" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">
            <el-link type="primary" @click="handleEdit(row)">{{ row.name }}</el-link>
          </template>
        </el-table-column>
        <el-table-column prop="lssName" :label="t('LSS')" min-width="120" show-overflow-tooltip>
          <template #default="{ row }">
            <span>{{ row.lssName ? `${row.lssId}/${row.lssName}` : '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="cameraName" :label="t('摄像头编号')" min-width="150" show-overflow-tooltip>
          <template #default="{ row }">
            <span>{{ row.cameraName || '-' }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="streamMethod" :label="t('推流方式')" width="100" align="center">
          <template #default="{ row }">
            <el-tag size="small">{{ row.streamMethod }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="commandTemplate" :label="t('命令模板')" width="90" align="center">
          <template #default="{ row }">
            <el-link v-if="row.commandTemplate" type="primary" @click="showCommandTemplate(row)">
              {{ t('查看') }}
            </el-link>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column :label="t('操作')" width="100" align="center">
          <template #default="{ row }">
            <el-button
              v-if="row.status !== 'running'"
              type="primary"
              link
              :loading="actionLoading[row.id]"
              @click="handleStart(row)"
            >
              {{ t('启动') }}
            </el-button>
            <el-button v-else type="danger" link :loading="actionLoading[row.id]" @click="handleStop(row)">
              {{ t('关闭') }}
            </el-button>
          </template>
        </el-table-column>
        <el-table-column prop="startedAt" :label="t('启动时间')" width="160" align="center">
          <template #default="{ row }">
            {{ formatDateTime(row.startedAt) }}
          </template>
        </el-table-column>
        <el-table-column prop="stoppedAt" :label="t('关闭时间')" width="160" align="center">
          <template #default="{ row }">
            {{ formatDateTime(row.stoppedAt) }}
          </template>
        </el-table-column>
        <el-table-column :label="t('观看')" width="80" align="center">
          <template #default="{ row }">
            <el-button
              type="primary"
              link
              :icon="View"
              :disabled="row.status !== 'running'"
              @click="handleWatch(row)"
            />
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- 分页 -->
    <div class="pagination-container">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="total"
        layout="total, sizes, prev, pager, next, jumper"
        background
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 新增/编辑弹窗 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="550px" destroy-on-close>
      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
        <el-form-item :label="t('Stream SN')" prop="streamSn">
          <el-input v-model="form.streamSn" placeholder="自动生成" disabled />
        </el-form-item>
        <el-form-item :label="t('名称')" prop="name">
          <el-input v-model="form.name" placeholder="请输入名称" />
        </el-form-item>
        <el-form-item :label="t('LSS')" prop="lssId">
          <el-select v-model="form.lssId" placeholder="请选择 LSS" clearable filterable style="width: 100%">
            <el-option v-for="lss in lssOptions" :key="lss.id" :label="`${lss.lssId} / ${lss.name}`" :value="lss.id" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('摄像头')" prop="cameraId">
          <el-select v-model="form.cameraId" placeholder="请选择摄像头" clearable filterable style="width: 100%">
            <el-option
              v-for="camera in cameraOptions"
              :key="camera.id"
              :label="`${camera.cameraId} / ${camera.name}`"
              :value="camera.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('推流方式')" prop="streamMethod">
          <el-select v-model="form.streamMethod" placeholder="请选择推流方式" style="width: 100%">
            <el-option label="ffmpeg" value="ffmpeg" />
            <el-option label="obs" value="obs" />
            <el-option label="gstreamer" value="gstreamer" />
          </el-select>
        </el-form-item>
        <el-form-item :label="t('命令模板')" prop="commandTemplate">
          <el-input v-model="form.commandTemplate" type="textarea" :rows="4" placeholder="请输入命令模板" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">{{ t('取消') }}</el-button>
        <el-button type="primary" :loading="submitLoading" @click="handleSubmit">{{ t('确定') }}</el-button>
      </template>
    </el-dialog>

    <!-- 命令模板查看弹窗 -->
    <el-dialog v-model="templateDialogVisible" :title="t('命令模板')" width="600px">
      <pre class="command-template">{{ currentTemplate }}</pre>
      <template #footer>
        <el-button type="primary" @click="templateDialogVisible = false">{{ t('关闭') }}</el-button>
      </template>
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import { Search, RefreshRight, View } from '@element-plus/icons-vue'
import {
  listLiveStreams,
  addLiveStream,
  updateLiveStream,
  startLiveStream,
  stopLiveStream,
  getLssOptions,
  getCameraOptions
} from '@/api/live-stream'
import type { LiveStreamDTO, LssDTO, CameraInfoDTO, StreamMethod } from '@/types'
import dayjs from 'dayjs'
import { useI18n } from 'vue-i18n'

const { t } = useI18n({ useScope: 'global' })
const router = useRouter()

// 格式化时间
function formatDateTime(dateStr: string | undefined): string {
  if (!dateStr) return '-'
  return dayjs(dateStr).format('YYYYMMDD-HH:mm:ss')
}

const loading = ref(false)
const submitLoading = ref(false)
const actionLoading = ref<Record<number, boolean>>({})
const streamList = ref<LiveStreamDTO[]>([])
const dialogVisible = ref(false)
const templateDialogVisible = ref(false)
const formRef = ref<FormInstance>()
const currentTemplate = ref('')

// 下拉选项
const lssOptions = ref<LssDTO[]>([])
const cameraOptions = ref<CameraInfoDTO[]>([])

// 排序状态
const sortState = reactive<{
  prop: string
  order: 'ascending' | 'descending' | null
}>({
  prop: '',
  order: null
})

// 搜索表单
const searchForm = reactive({
  aoAgent: '',
  feature: ''
})

// 分页相关
const currentPage = ref(1)
const pageSize = ref(20)
const total = ref(0)

// 表单数据
const form = reactive<{
  id?: number
  streamSn: string
  name: string
  lssId?: number
  cameraId?: number
  streamMethod: StreamMethod
  commandTemplate: string
}>({
  streamSn: '',
  name: '',
  lssId: undefined,
  cameraId: undefined,
  streamMethod: 'ffmpeg',
  commandTemplate: ''
})

const isEdit = computed(() => !!form.id)
const dialogTitle = computed(() => (isEdit.value ? t('编辑 LiveStream') : t('新增 LiveStream')))

const rules: FormRules = {
  name: [{ required: true, message: t('请输入名称'), trigger: 'blur' }],
  streamMethod: [{ required: true, message: t('请选择推流方式'), trigger: 'change' }]
}

// 生成测试数据
function generateMockData(): LiveStreamDTO[] {
  const mockData: LiveStreamDTO[] = [
    {
      id: 1,
      streamSn: 'LS-20260119-001',
      name: '大厅摄像头直播',
      lssId: 1,
      lssName: 'LSS-Tokyo-01',
      cameraId: 101,
      cameraName: 'CAM-LOBBY-01',
      streamMethod: 'ffmpeg',
      commandTemplate:
        'ffmpeg -i rtsp://192.168.1.100:554/stream1 -c:v libx264 -preset ultrafast -tune zerolatency -f flv rtmp://live.example.com/app/stream1',
      status: 'running',
      startedAt: '2026-01-19T11:11:11',
      stoppedAt: undefined,
      playUrl: 'https://live.example.com/hls/stream1.m3u8',
      createdAt: '2026-01-15T10:00:00',
      updatedAt: '2026-01-19T11:11:11'
    },
    {
      id: 2,
      streamSn: 'LS-20260119-002',
      name: '入口监控',
      lssId: 1,
      lssName: 'LSS-Tokyo-01',
      cameraId: 102,
      cameraName: 'CAM-ENTRANCE-01',
      streamMethod: 'ffmpeg',
      commandTemplate:
        'ffmpeg -i rtsp://192.168.1.101:554/stream1 -c:v libx264 -f flv rtmp://live.example.com/app/stream2',
      status: 'stopped',
      startedAt: '2026-01-18T09:00:00',
      stoppedAt: '2026-01-18T18:00:00',
      playUrl: undefined,
      createdAt: '2026-01-15T10:30:00',
      updatedAt: '2026-01-18T18:00:00'
    },
    {
      id: 3,
      streamSn: 'LS-20260119-003',
      name: '仓库区域',
      lssId: 2,
      lssName: 'LSS-Osaka-01',
      cameraId: 103,
      cameraName: 'CAM-WAREHOUSE-01',
      streamMethod: 'obs',
      commandTemplate: undefined,
      status: 'running',
      startedAt: '2026-01-19T08:30:00',
      stoppedAt: undefined,
      playUrl: 'https://live.example.com/hls/stream3.m3u8',
      createdAt: '2026-01-16T14:00:00',
      updatedAt: '2026-01-19T08:30:00'
    },
    {
      id: 4,
      streamSn: 'LS-20260119-004',
      name: '停车场入口',
      lssId: 2,
      lssName: 'LSS-Osaka-01',
      cameraId: 104,
      cameraName: 'CAM-PARKING-01',
      streamMethod: 'ffmpeg',
      commandTemplate:
        'ffmpeg -i rtsp://192.168.1.104:554/ch1 -c:v copy -c:a aac -f flv rtmp://live.example.com/app/parking',
      status: 'error',
      startedAt: '2026-01-19T07:00:00',
      stoppedAt: '2026-01-19T07:15:00',
      playUrl: undefined,
      createdAt: '2026-01-17T09:00:00',
      updatedAt: '2026-01-19T07:15:00'
    },
    {
      id: 5,
      streamSn: 'LS-20260119-005',
      name: '会议室A',
      lssId: 1,
      lssName: 'LSS-Tokyo-01',
      cameraId: 105,
      cameraName: 'CAM-MEETING-A',
      streamMethod: 'gstreamer',
      commandTemplate:
        'gst-launch-1.0 rtspsrc location=rtsp://192.168.1.105:554/stream ! rtph264depay ! h264parse ! flvmux ! rtmpsink location=rtmp://live.example.com/app/meetingA',
      status: 'stopped',
      startedAt: undefined,
      stoppedAt: undefined,
      playUrl: undefined,
      createdAt: '2026-01-18T11:00:00',
      updatedAt: '2026-01-18T11:00:00'
    }
  ]
  return mockData
}

// 生成测试 LSS 选项
function generateMockLssOptions(): LssDTO[] {
  return [
    {
      id: 1,
      lssId: 'LSS-001',
      name: 'LSS-Tokyo-01',
      address: '192.168.1.10',
      publicIp: '203.0.113.10',
      heartbeat: 'active',
      heartbeatTime: '2026-01-19T12:00:00'
    },
    {
      id: 2,
      lssId: 'LSS-002',
      name: 'LSS-Osaka-01',
      address: '192.168.2.10',
      publicIp: '203.0.113.20',
      heartbeat: 'active',
      heartbeatTime: '2026-01-19T12:00:00'
    },
    {
      id: 3,
      lssId: 'LSS-003',
      name: 'LSS-Nagoya-01',
      address: '192.168.3.10',
      publicIp: '203.0.113.30',
      heartbeat: 'hold',
      heartbeatTime: '2026-01-19T11:50:00'
    }
  ]
}

// 生成测试摄像头选项
function generateMockCameraOptions(): CameraInfoDTO[] {
  return [
    {
      id: 101,
      cameraId: 'CAM-001',
      name: 'CAM-LOBBY-01',
      ip: '192.168.1.100',
      port: 554,
      username: 'admin',
      brand: 'HIKVISION',
      capability: 'ptz_enabled',
      status: 'ONLINE',
      machineId: 'M001',
      machineName: '机器1',
      enabled: true,
      channels: [],
      createdAt: '2026-01-01',
      updatedAt: '2026-01-19'
    },
    {
      id: 102,
      cameraId: 'CAM-002',
      name: 'CAM-ENTRANCE-01',
      ip: '192.168.1.101',
      port: 554,
      username: 'admin',
      brand: 'DAHUA',
      capability: 'switch_only',
      status: 'ONLINE',
      machineId: 'M001',
      machineName: '机器1',
      enabled: true,
      channels: [],
      createdAt: '2026-01-01',
      updatedAt: '2026-01-19'
    },
    {
      id: 103,
      cameraId: 'CAM-003',
      name: 'CAM-WAREHOUSE-01',
      ip: '192.168.1.102',
      port: 554,
      username: 'admin',
      brand: 'HIKVISION',
      capability: 'ptz_enabled',
      status: 'ONLINE',
      machineId: 'M002',
      machineName: '机器2',
      enabled: true,
      channels: [],
      createdAt: '2026-01-01',
      updatedAt: '2026-01-19'
    },
    {
      id: 104,
      cameraId: 'CAM-004',
      name: 'CAM-PARKING-01',
      ip: '192.168.1.104',
      port: 554,
      username: 'admin',
      brand: 'AXIS',
      capability: 'switch_only',
      status: 'OFFLINE',
      machineId: 'M002',
      machineName: '机器2',
      enabled: true,
      channels: [],
      createdAt: '2026-01-01',
      updatedAt: '2026-01-19'
    },
    {
      id: 105,
      cameraId: 'CAM-005',
      name: 'CAM-MEETING-A',
      ip: '192.168.1.105',
      port: 554,
      username: 'admin',
      brand: 'SONY',
      capability: 'ptz_enabled',
      status: 'ONLINE',
      machineId: 'M001',
      machineName: '机器1',
      enabled: true,
      channels: [],
      createdAt: '2026-01-01',
      updatedAt: '2026-01-19'
    }
  ]
}

async function getList() {
  loading.value = true
  try {
    // 使用测试数据（后端 API 准备好后可切换）
    const useMockData = true

    if (useMockData) {
      // 模拟网络延迟
      await new Promise((resolve) => setTimeout(resolve, 300))
      let mockData = generateMockData()

      // 搜索过滤
      if (searchForm.aoAgent) {
        mockData = mockData.filter(
          (item) =>
            item.streamSn.toLowerCase().includes(searchForm.aoAgent.toLowerCase()) ||
            item.name.toLowerCase().includes(searchForm.aoAgent.toLowerCase())
        )
      }

      streamList.value = mockData
      total.value = mockData.length
    } else {
      const params: Record<string, any> = {
        page: currentPage.value,
        size: pageSize.value
      }
      if (searchForm.aoAgent) {
        params.aoAgent = searchForm.aoAgent
      }
      if (searchForm.feature) {
        params.feature = searchForm.feature
      }
      if (sortState.prop && sortState.order) {
        params.sortBy = sortState.prop
        params.sortDir = sortState.order === 'ascending' ? 'ASC' : 'DESC'
      }

      const res = await listLiveStreams(params)
      if (res.success) {
        streamList.value = res.data.list
        total.value = res.data.total || 0
      }
    }
  } finally {
    loading.value = false
  }
}

async function loadOptions() {
  const useMockData = true

  if (useMockData) {
    lssOptions.value = generateMockLssOptions()
    cameraOptions.value = generateMockCameraOptions()
    return
  }

  try {
    const [lssRes, cameraRes] = await Promise.all([getLssOptions(), getCameraOptions()])
    if (lssRes.success && lssRes.data) {
      lssOptions.value = lssRes.data
    }
    if (cameraRes.success && cameraRes.data) {
      cameraOptions.value = cameraRes.data
    }
  } catch (error) {
    console.error('加载选项失败', error)
  }
}

function handleSearch() {
  currentPage.value = 1
  getList()
}

function handleReset() {
  searchForm.aoAgent = ''
  searchForm.feature = ''
  currentPage.value = 1
  sortState.prop = ''
  sortState.order = null
  getList()
}

function handleSortChange({ prop, order }: { prop: string; order: 'ascending' | 'descending' | null }) {
  sortState.prop = prop || ''
  sortState.order = order
  getList()
}

function handleEdit(row: LiveStreamDTO) {
  Object.assign(form, {
    id: row.id,
    streamSn: row.streamSn,
    name: row.name,
    lssId: row.lssId,
    cameraId: row.cameraId,
    streamMethod: row.streamMethod,
    commandTemplate: row.commandTemplate || ''
  })
  dialogVisible.value = true
}

function showCommandTemplate(row: LiveStreamDTO) {
  currentTemplate.value = row.commandTemplate || ''
  templateDialogVisible.value = true
}

async function handleStart(row: LiveStreamDTO) {
  actionLoading.value[row.id] = true
  try {
    const res = await startLiveStream(row.id)
    if (res.success) {
      ElMessage.success(t('启动成功'))
      getList()
    }
  } catch (error: any) {
    ElMessage.error(error.message || t('启动失败'))
  } finally {
    actionLoading.value[row.id] = false
  }
}

async function handleStop(row: LiveStreamDTO) {
  actionLoading.value[row.id] = true
  try {
    const res = await stopLiveStream(row.id)
    if (res.success) {
      ElMessage.success(t('已关闭'))
      getList()
    }
  } catch (error: any) {
    ElMessage.error(error.message || t('关闭失败'))
  } finally {
    actionLoading.value[row.id] = false
  }
}

function handleWatch(row: LiveStreamDTO) {
  // 跳转到 Cloudflare Stream 页面，带上 stream 信息
  router.push({
    path: '/cc',
    query: {
      streamSn: row.streamSn,
      name: row.name,
      playUrl: row.playUrl || ''
    }
  })
}

async function handleSubmit() {
  if (!formRef.value) return

  await formRef.value.validate(async (valid) => {
    if (valid) {
      submitLoading.value = true
      try {
        if (isEdit.value) {
          const res = await updateLiveStream({
            id: form.id!,
            name: form.name,
            lssId: form.lssId,
            cameraId: form.cameraId,
            streamMethod: form.streamMethod,
            commandTemplate: form.commandTemplate || undefined
          })
          if (res.success) {
            ElMessage.success(t('修改成功'))
            dialogVisible.value = false
            getList()
          }
        } else {
          const res = await addLiveStream({
            name: form.name,
            lssId: form.lssId,
            cameraId: form.cameraId,
            streamMethod: form.streamMethod,
            commandTemplate: form.commandTemplate || undefined
          })
          if (res.success) {
            ElMessage.success(t('新增成功'))
            dialogVisible.value = false
            getList()
          }
        }
      } finally {
        submitLoading.value = false
      }
    }
  })
}

function handleSizeChange(val: number) {
  pageSize.value = val
  currentPage.value = 1
  getList()
}

function handleCurrentChange(val: number) {
  currentPage.value = val
  getList()
}

onMounted(() => {
  getList()
  loadOptions()
})
</script>

<style lang="scss" scoped>
.page-container {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

.search-form {
  flex-shrink: 0;
  margin-bottom: 16px;
  padding: 16px 16px 4px 16px;
  background: #f5f7fa;

  :deep(.el-form-item) {
    margin-bottom: 12px;
    margin-right: 16px;
  }

  :deep(.el-input),
  :deep(.el-select) {
    width: 160px;
  }

  :deep(.el-button--primary) {
    background-color: #4f46e5;
    border-color: #4f46e5;

    &:hover,
    &:focus {
      background-color: #6366f1;
      border-color: #6366f1;
    }
  }
}

.table-wrapper {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.pagination-container {
  flex-shrink: 0;
  display: flex;
  justify-content: flex-end;
  padding-top: 16px;

  :deep(.el-pagination) {
    .el-pager li.is-active {
      background-color: #4f46e5;
      color: #fff;
    }

    .el-pager li:not(.is-active):hover {
      color: #4f46e5;
    }

    .btn-prev:hover,
    .btn-next:hover {
      color: #4f46e5;
    }
  }
}

:deep(.el-table) {
  --el-table-row-hover-bg-color: #f0f0ff;

  .el-table__row--striped td.el-table__cell {
    background-color: #f8f9fc;
  }

  .el-table__header th {
    background-color: #f5f7fa;
    color: #333;
    font-weight: 600;
  }

  .el-link--primary {
    color: #4f46e5;

    &:hover {
      color: #6366f1;
    }
  }

  .el-button--primary.is-link {
    color: #4f46e5;

    &:hover {
      color: #6366f1;
    }
  }
}

:deep(.el-dialog) {
  .el-dialog__header {
    border-bottom: 1px solid #e5e7eb;
    padding-bottom: 16px;
  }

  .el-dialog__footer {
    border-top: 1px solid #e5e7eb;
    padding-top: 16px;
  }

  .el-button--primary {
    background-color: #4f46e5;
    border-color: #4f46e5;

    &:hover,
    &:focus {
      background-color: #6366f1;
      border-color: #6366f1;
    }
  }
}

.command-template {
  background: #f5f7fa;
  padding: 16px;
  border-radius: 4px;
  font-family: monospace;
  font-size: 13px;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 400px;
  overflow: auto;
}
</style>
