<template>
  <div class="p-2">
    <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
      <div v-show="showSearch" class="mb-[10px]">
        <el-card shadow="hover">
          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
            <el-form-item label="采集设备编号" prop="deviceCode">
              <el-input v-model="queryParams.deviceCode" placeholder="请输入采集设备编号" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="采集设备名称" prop="deviceName">
              <el-input v-model="queryParams.deviceName" placeholder="请输入采集设备名称" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item label="设备类型" prop="deviceType">
              <el-select v-model="queryParams.deviceType" placeholder="请选择设备类型" clearable>
                <el-option v-for="dict in communication_device_type" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
            <el-form-item label="安装位置" prop="installPosition">
              <el-cascader v-model="queryParams.installPosition" :options="floorOptions" :props="floorCascaderProps" placeholder="请选择安装位置" clearable filterable />
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-input v-model="queryParams.status" placeholder="请输入状态" clearable @keyup.enter="handleQuery" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </div>
    </transition>

    <el-card shadow="hover">
      <template #header>
        <el-row :gutter="10">
          <el-col :span="1.5">
            <el-button type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()">修改</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()">删除</el-button>
          </el-col>
          <right-toolbar v-model:show-search="showSearch" @query-table="getList" />
        </el-row>
      </template>

      <el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="采集设备编号" prop="deviceCode" min-width="150" />
        <el-table-column label="采集设备名称" prop="deviceName" min-width="150" />
        <el-table-column label="设备类型" align="center" min-width="150">
          <template #default="scope">
            <dict-tag :options="communication_device_type" :value="scope.row.deviceType" />
          </template>
        </el-table-column>
        <el-table-column label="生产厂家" prop="manufacturer" min-width="140" />
        <el-table-column label="规格型号" prop="specificationModel" min-width="130" />
        <el-table-column label="序列号/SN" prop="serialNo" min-width="140" />
        <el-table-column label="资产编号" prop="assetNo" min-width="130" />
        <el-table-column label="安装位置" prop="installPositionName" min-width="220" show-overflow-tooltip />
        <el-table-column label="状态" prop="status" width="90" />
        <el-table-column label="责任人" prop="responsiblePerson" width="110" />
        <el-table-column label="绑定计量设备" prop="bindCount" align="right" width="120" />
        <el-table-column fixed="right" label="操作" align="center" width="150">
          <template #default="scope">
            <el-tooltip content="绑定计量设备" placement="top">
              <el-button link type="primary" icon="Connection" @click="handleBind(scope.row)" />
            </el-tooltip>
            <el-tooltip content="修改" placement="top">
              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" />
            </el-tooltip>
            <el-tooltip content="删除" placement="top">
              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" />
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>

      <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
    </el-card>

    <el-dialog v-model="dialog.visible" :title="dialog.title" append-to-body width="720px">
      <el-form ref="deviceFormRef" :model="form" :rules="rules" label-width="120px">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="采集设备编号" prop="deviceCode">
              <el-input v-model="form.deviceCode" placeholder="请输入采集设备编号" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="采集设备名称" prop="deviceName">
              <el-input v-model="form.deviceName" placeholder="请输入采集设备名称" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="设备类型" prop="deviceType">
              <el-select v-model="form.deviceType" placeholder="请选择设备类型" filterable>
                <el-option v-for="dict in communication_device_type" :key="dict.value" :label="dict.label" :value="dict.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="生产厂家">
              <el-input v-model="form.manufacturer" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号">
              <el-input v-model="form.specificationModel" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="序列号/SN">
              <el-input v-model="form.serialNo" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="资产编号">
              <el-input v-model="form.assetNo" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="安装位置" prop="installPosition">
              <el-cascader v-model="form.installPosition" :options="floorOptions" :props="floorCascaderProps" clearable filterable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="状态">
              <el-input v-model="form.status" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="责任人">
              <el-input v-model="form.responsiblePerson" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <el-dialog v-model="bindDialog.visible" title="绑定计量设备" append-to-body width="860px">
      <div class="bind-toolbar">
        <el-select v-model="bindDeviceId" filterable clearable placeholder="输入设备编号快速选择计量设备" class="bind-device-select">
          <el-option
            v-for="item in unboundDeviceOptions"
            :key="item.id"
            :label="`${item.deviceCode || item.deviceId || ''} ${item.deviceName || ''}`"
            :value="item.id"
          >
            <span>{{ item.deviceCode || item.deviceId }}</span>
            <span class="bind-option-extra">{{ item.deviceName }}</span>
            <span v-if="item.collectingDeviceName" class="bind-option-extra">当前：{{ item.collectingDeviceName }}</span>
          </el-option>
        </el-select>
        <el-button type="primary" icon="Plus" :disabled="!bindDeviceId" @click="addBindDevice">添加</el-button>
      </div>
      <el-table v-loading="bindLoading" border :data="boundMeasuringDevices" row-key="id" max-height="460">
        <el-table-column label="设备ID" prop="deviceId" min-width="120" />
        <el-table-column label="设备名称" prop="deviceName" min-width="140" />
        <el-table-column label="设备编号" prop="deviceCode" min-width="140" />
        <el-table-column label="设备类型" align="center" width="110">
          <template #default="scope">
            <dict-tag :options="device_type" :value="scope.row.deviceType" />
          </template>
        </el-table-column>
        <el-table-column label="安装位置" prop="installPositionName" min-width="220" show-overflow-tooltip />
        <el-table-column label="当前采集设备" prop="collectingDeviceName" min-width="150" show-overflow-tooltip />
        <el-table-column label="操作" align="center" width="90">
          <template #default="scope">
            <el-button link type="primary" icon="Delete" @click="removeBindDevice(scope.row)" />
          </template>
        </el-table-column>
      </el-table>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitBind">确 定</el-button>
          <el-button @click="bindDialog.visible = false">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="CollectingDevice" lang="ts">
import {
  addCollectingDevice,
  bindMeasuringDevices,
  delCollectingDevice,
  getCollectingDevice,
  listCollectingDevice,
  updateCollectingDevice
} from '@/api/ems/collectingDevice';
import { CollectingDeviceForm, CollectingDeviceQuery, CollectingDeviceVO } from '@/api/ems/collectingDevice/types';
import { listMeasuringDevice } from '@/api/ems/measuringDevice';
import { MeasuringDeviceVO } from '@/api/ems/measuringDevice/types';
import { listFloorInfo } from '@/api/system/floor';
import { FloorInfoVO } from '@/api/system/floor/types';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { communication_device_type, device_type } = toRefs<any>(proxy?.useDict('communication_device_type', 'device_type'));

const deviceList = ref<CollectingDeviceVO[]>([]);
const floorOptions = ref<any[]>([]);
const measuringDeviceOptions = ref<MeasuringDeviceVO[]>([]);
const loading = ref(false);
const bindLoading = ref(false);
const showSearch = ref(true);
const total = ref(0);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const currentBindDevice = ref<CollectingDeviceVO>();
const boundMeasuringDevices = ref<MeasuringDeviceVO[]>([]);
const bindDeviceId = ref<string | number>();
const floorCascaderProps = { value: 'id', label: 'name', children: 'children', emitPath: false, checkStrictly: true };

const queryFormRef = ref<ElFormInstance>();
const deviceFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({ visible: false, title: '' });
const bindDialog = reactive<DialogOption>({ visible: false, title: '' });

const initFormData: CollectingDeviceForm = {
  id: undefined,
  deviceCode: '',
  deviceName: '',
  deviceType: undefined,
  manufacturer: '',
  specificationModel: '',
  serialNo: '',
  assetNo: '',
  installPosition: undefined,
  status: '',
  responsiblePerson: ''
};

const data = reactive<PageData<CollectingDeviceForm, CollectingDeviceQuery>>({
  form: { ...initFormData },
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    deviceCode: '',
    deviceName: '',
    deviceType: undefined,
    installPosition: undefined,
    status: ''
  },
  rules: {
    deviceCode: [{ required: true, message: '采集设备编号不能为空', trigger: 'blur' }],
    deviceName: [{ required: true, message: '采集设备名称不能为空', trigger: 'blur' }],
    deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'change' }]
  }
});

const { queryParams, form, rules } = toRefs(data);

const unboundDeviceOptions = computed(() =>
  measuringDeviceOptions.value.filter((item) => !boundMeasuringDevices.value.some((bound) => String(bound.id) === String(item.id)))
);

const normalizeFloorTree = (rows: FloorInfoVO[]): any[] =>
  rows
    .filter((row) => row.isDevice !== '1' && row.isDeviceGroup !== '1')
    .map((row) => ({
      id: row.id,
      name: row.name,
      children: normalizeFloorTree((row.children || []).filter((child) => child.isDevice !== '1' && child.isDeviceGroup !== '1'))
    }));

const loadOptions = async () => {
  const floorRes = await listFloorInfo();
  floorOptions.value = normalizeFloorTree((floorRes as any).rows || []);
};

const getList = async () => {
  loading.value = true;
  try {
    const res = await listCollectingDevice(queryParams.value);
    deviceList.value = res.rows || [];
    total.value = res.total || 0;
  } finally {
    loading.value = false;
  }
};

const reset = () => {
  form.value = { ...initFormData };
  deviceFormRef.value?.resetFields();
};

const handleQuery = () => {
  queryParams.value.pageNum = 1;
  getList();
};

const resetQuery = () => {
  queryFormRef.value?.resetFields();
  handleQuery();
};

const handleSelectionChange = (selection: CollectingDeviceVO[]) => {
  ids.value = selection.map((item) => item.id);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
};

const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = '新增采集设备';
};

const handleUpdate = async (row?: CollectingDeviceVO) => {
  reset();
  const id = row?.id || ids.value[0];
  const res = await getCollectingDevice(id);
  form.value = { ...res.data };
  dialog.visible = true;
  dialog.title = '修改采集设备';
};

const submitForm = () => {
  deviceFormRef.value?.validate(async (valid: boolean) => {
    if (!valid) return;
    if (form.value.id) {
      await updateCollectingDevice(form.value);
    } else {
      await addCollectingDevice(form.value);
    }
    proxy?.$modal.msgSuccess('操作成功');
    dialog.visible = false;
    await getList();
  });
};

const handleDelete = async (row?: CollectingDeviceVO) => {
  const deleteIds = row?.id || ids.value;
  await proxy?.$modal.confirm('是否确认删除采集设备编号为"' + deleteIds + '"的数据项？');
  await delCollectingDevice(deleteIds);
  proxy?.$modal.msgSuccess('删除成功');
  await getList();
};

const handleBind = async (row: CollectingDeviceVO) => {
  currentBindDevice.value = row;
  bindDialog.visible = true;
  bindDeviceId.value = undefined;
  bindLoading.value = true;
  try {
    const res = await listMeasuringDevice({ pageNum: 1, pageSize: 1000 });
    measuringDeviceOptions.value = res.rows || [];
    boundMeasuringDevices.value = measuringDeviceOptions.value.filter((item) => String(item.collectingDeviceId || '') === String(row.id));
  } finally {
    bindLoading.value = false;
  }
};

const addBindDevice = () => {
  const selected = measuringDeviceOptions.value.find((item) => String(item.id) === String(bindDeviceId.value));
  if (!selected) return;
  if (!boundMeasuringDevices.value.some((item) => String(item.id) === String(selected.id))) {
    boundMeasuringDevices.value.push(selected);
  }
  bindDeviceId.value = undefined;
};

const removeBindDevice = (row: MeasuringDeviceVO) => {
  boundMeasuringDevices.value = boundMeasuringDevices.value.filter((item) => String(item.id) !== String(row.id));
};

const submitBind = async () => {
  if (!currentBindDevice.value?.id) return;
  await bindMeasuringDevices({
    id: currentBindDevice.value.id,
    measuringDeviceIds: boundMeasuringDevices.value.map((item) => item.id)
  });
  proxy?.$modal.msgSuccess('绑定成功');
  bindDialog.visible = false;
  await getList();
};

const cancel = () => {
  dialog.visible = false;
  reset();
};

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

<style scoped>
.bind-toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.bind-device-select {
  flex: 1;
}

.bind-option-extra {
  margin-left: 12px;
  color: var(--el-text-color-secondary);
}
</style>
