<style scoped lang="scss">
.system-container {
  :deep(.el-card__body) {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    flex: 1;
    overflow: auto;

    .el-table {
      flex: 1;
    }
  }
}

.page-content {
  margin-bottom: 20px;
}

.page-pager {
  background-color: var(--el-color-white);
  height: 24px;
}

.qrcode-img {
  width: 260px;
  height: 260px;
  margin: 20px auto;
  display: block;
  border: 1px solid #eee;
}

.qrcode-tip {
  text-align: center;
  color: #999;
  font-size: 13px;
  margin-top: 10px;
}

.fault-tag {
  margin-right: 8px;
}
</style>
<template>
  <div class="system-container layout-padding">
    <el-card shadow="hover" class="layout-padding-auto">
      <el-tabs v-model="state.activeTab" @tab-click="handleTabClick">
        <!-- ==================== 订阅管理 ==================== -->
        <el-tab-pane label="订阅管理" name="subscriber">
          <el-form :model="state.formQuery" ref="queryRef" size="default" label-width="0px" class="mt5 mb5">
            <ext-select
                v-model="state.formQuery.stationId"
                placeholder="请选择站点"
                url="washStation/list"
                url-method="post"
                label-key="stationName"
                value-key="stationId"
                data-key="list"
                clearable
                class="wd200"
                @change="loadSubscribers(true)"/>
            <el-button class="ml10" plain size="default" type="success" @click="loadSubscribers(true)">
              <SvgIcon name="ele-Search"/>
              查询
            </el-button>
            <el-button v-if="state.formQuery.stationId" class="ml10" plain size="default" type="primary" @click="handleGenerateQrcode">
              <SvgIcon name="ele-Picture"/>
              生成绑定二维码
            </el-button>
          </el-form>

          <el-table
              border stripe
              :height="state.tableHeight"
              :data="state.subscriberData"
              v-loading="state.subscriberLoading">
            <template #empty>
              <el-empty description="请选择站点后查询"/>
            </template>
            <el-table-column label="OpenID" prop="openid" width="260" show-overflow-tooltip/>
            <el-table-column label="昵称" prop="nickname" width="150"/>
            <el-table-column label="站点" prop="stationId" width="120"/>
            <el-table-column label="绑定时间" prop="subscribeTime" width="170">
              <template #default="{row}">{{ u.fmt.fmtDateTime(row.subscribeTime) }}</template>
            </el-table-column>
            <el-table-column label="状态" prop="status" width="90">
              <template #default="{row}">
                <el-tag :type="row.status === 1 ? 'success' : 'info'" size="small">
                  {{ row.status === 1 ? '已订阅' : '已解绑' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="100" align="center" fixed="right">
              <template #default="{row}">
                <el-button v-if="row.status === 1" type="danger" text size="small" @click="handleUnsubscribe(row)">解绑</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>

        <!-- ==================== 故障记录 ==================== -->
        <el-tab-pane label="故障记录" name="faultRecord">
          <el-form :model="state.faultQuery" size="default" label-width="0px" class="mt5 mb5">
            <ext-select
                v-model="state.faultQuery.stationId"
                placeholder="站点（可选）"
                url="washStation/list"
                url-method="post"
                label-key="stationName"
                value-key="stationId"
                data-key="list"
                clearable
                class="wd200"/>
            <el-select v-model="state.faultQuery.faultType" placeholder="故障类型" clearable class="wd150 ml10">
              <el-option label="设备离线" value="offline"/>
              <el-option label="缺水" value="water_shortage"/>
              <el-option label="缺泡沫" value="foam_shortage"/>
            </el-select>
            <el-select v-model="state.faultQuery.isRecovered" placeholder="恢复状态" clearable class="wd150 ml10">
              <el-option label="未恢复" :value="0"/>
              <el-option label="已恢复" :value="1"/>
            </el-select>
            <el-button class="ml10" plain size="default" type="success" @click="loadFaultRecords(true)">
              <SvgIcon name="ele-Search"/>
              查询
            </el-button>
          </el-form>

          <el-table
              border stripe
              :height="state.tableHeight"
              :data="state.faultRecordData"
              v-loading="state.faultRecordLoading">
            <template #empty>
              <el-empty description="暂无故障记录"/>
            </template>
            <el-table-column label="站点" prop="stationId" width="100"/>
            <el-table-column label="设备" prop="deviceName" width="150"/>
            <el-table-column label="故障类型" prop="faultType" width="110">
              <template #default="{row}">
                <el-tag class="fault-tag"
                    :type="row.faultType === 'offline' ? 'danger' : 'warning'"
                    size="small">
                  {{ faultTypeLabel(row.faultType) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="故障时间" prop="faultTime" width="170">
              <template #default="{row}">{{ u.fmt.fmtDateTime(row.faultTime) }}</template>
            </el-table-column>
            <el-table-column label="是否通知" prop="isNotified" width="90">
              <template #default="{row}">
                <el-tag :type="row.isNotified === 1 ? 'success' : 'warning'" size="small">
                  {{ row.isNotified === 1 ? '已通知' : '未通知' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="通知时间" prop="notifyTime" width="170">
              <template #default="{row}">{{ row.notifyTime ? u.fmt.fmtDateTime(row.notifyTime) : '-' }}</template>
            </el-table-column>
            <el-table-column label="是否恢复" prop="isRecovered" width="90">
              <template #default="{row}">
                <el-tag :type="row.isRecovered === 1 ? 'success' : 'danger'" size="small">
                  {{ row.isRecovered === 1 ? '已恢复' : '未恢复' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column label="恢复时间" prop="recoverTime" width="170">
              <template #default="{row}">{{ row.recoverTime ? u.fmt.fmtDateTime(row.recoverTime) : '-' }}</template>
            </el-table-column>
          </el-table>

          <ext-page class="page-pager" v-model:value="state.faultPageQuery" @change="loadFaultRecords(false)"/>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <!-- 二维码弹窗 -->
    <el-dialog v-model="state.qrcodeDialogVisible" title="故障通知绑定二维码" width="420px" center>
      <div style="text-align: center">
        <img v-if="state.qrcodeUrl" :src="state.qrcodeUrl" class="qrcode-img" alt="绑定二维码"/>
        <div class="qrcode-tip">
          请使用微信扫描二维码<br/>
          扫描后关注公众号即可绑定，再次扫描可解绑<br/>
          站点：{{ state.formQuery.stationId }}
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="adminStationFault">
import {reactive, onMounted, onBeforeMount, ref, nextTick, onBeforeUnmount} from 'vue';
import {$body, $get} from "/@/utils/request";
import u from '/@/utils/u'
import {Msg} from "/@/utils/message";

import ExtPage from '/@/components/form/ExtPage.vue'
import ExtSelect from "/@/components/form/ExtSelect.vue";
import mittBus from '/@/utils/mitt';


const state = reactive({
  activeTab: 'subscriber',
  tableHeight: 400,
  formQuery: {
    stationId: '' as string
  },
  subscriberData: [] as Array<any>,
  subscriberLoading: false,

  faultQuery: {
    stationId: '' as string,
    faultType: '' as string,
    isRecovered: null as number | null
  },
  faultRecordData: [] as Array<any>,
  faultRecordLoading: false,
  faultPageQuery: {
    pageNum: 1,
    pageSize: 10,
    total: 0
  },

  qrcodeDialogVisible: false,
  qrcodeUrl: '',
  qrcodeTicket: ''
});

const faultTypeLabel = (type: string) => {
  switch (type) {
    case 'offline': return '设备离线';
    case 'water_shortage': return '缺水';
    case 'foam_shortage': return '缺泡沫';
    default: return type;
  }
};

const handleTabClick = () => {
  if (state.activeTab === 'faultRecord') {
    loadFaultRecords(true);
  }
};

// ============ 订阅管理 ============

const loadSubscribers = (refresh: boolean = false) => {
  if (!state.formQuery.stationId) {
    state.subscriberData = [];
    return;
  }
  state.subscriberLoading = true;
  $get('/faultSubscriber/list', { stationId: state.formQuery.stationId }).then((res: any) => {
    state.subscriberData = res.data || res || [];
    state.subscriberLoading = false;
  }).catch(() => {
    state.subscriberLoading = false;
  });
};

const handleGenerateQrcode = () => {
  if (!state.formQuery.stationId) {
    Msg.message('请先选择站点', 'warning');
    return;
  }
  Msg.showLoading('生成中...');
  $body('/faultSubscriber/generateQrcode', { stationId: state.formQuery.stationId }).then((res: any) => {
    Msg.hideLoading();
    const data = res.data || res;
    state.qrcodeUrl = data.url;
    state.qrcodeTicket = data.ticket;
    state.qrcodeDialogVisible = true;
  }).catch(() => {
    Msg.hideLoading();
    Msg.message('生成二维码失败', 'error');
  });
};

const handleUnsubscribe = (row: any) => {
  Msg.confirm(`确定要解绑 ${row.openid} 吗？解绑后该用户将不再接收故障通知。`).then(() => {
    $body('/faultSubscriber/unsubscribe', { openid: row.openid, stationId: row.stationId }).then(() => {
      Msg.message('解绑成功', 'success');
      loadSubscribers(false);
    }).catch(() => {
      Msg.message('解绑失败', 'error');
    });
  }).catch(() => {});
};

// ============ 故障记录 ============

const loadFaultRecords = (refresh: boolean = false) => {
  if (refresh) {
    state.faultPageQuery.pageNum = 1;
  }
  state.faultRecordLoading = true;
  const params: any = { ...state.faultPageQuery };
  if (state.faultQuery.stationId) params.stationId = state.faultQuery.stationId;
  if (state.faultQuery.faultType) params.faultType = state.faultQuery.faultType;
  if (state.faultQuery.isRecovered !== null && state.faultQuery.isRecovered !== undefined) {
    params.isRecovered = state.faultQuery.isRecovered;
  }
  $get('/faultSubscriber/faultRecords', params).then((res: any) => {
    const list = res.data || res || [];
    if (Array.isArray(list)) {
      state.faultRecordData = list;
      state.faultPageQuery.total = list.length;
    } else if (list.list) {
      state.faultRecordData = list.list;
      state.faultPageQuery.total = list.total || 0;
    } else {
      state.faultRecordData = list;
    }
    state.faultRecordLoading = false;
  }).catch(() => {
    state.faultRecordLoading = false;
  });
};

// ============ 生命周期 ============

onBeforeMount(() => {
});

onMounted(() => {
  nextTick(() => {
    let bodyHeight = document.body.clientHeight;
    state.tableHeight = bodyHeight - 280;
  });

  mittBus.on("faultSubscriber.refresh", () => {
    loadSubscribers(false);
  });
});

onBeforeUnmount(() => {
  mittBus.off("faultSubscriber.refresh");
});
</script>
