<script setup lang="ts">
import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table';

import { h, nextTick, onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';

import { Page, useVbenModal, z } from '@vben/common-ui';

import { Button, message as Message, Tag } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
  postDeviceThingModelManagementBuildAnalysisScriptAsync,
  postDeviceThingModelManagementBuildAnalysisScriptByIdAsync,
  postDeviceThingModelManagementCreateAsync,
  postDeviceThingModelManagementDeleteAsync,
  postDeviceThingModelManagementMessageAnalysisTestAsync,
  postDeviceThingModelManagementPageAsync,
  postDeviceThingModelManagementUpdateAnalysisScriptByIdAsync,
  postDeviceThingModelManagementUpdateAsync,
} from '#/api-client';
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';

import DeviceThingModelCommandModal from './DeviceThingModelCommandModal.vue';
import DeviceThingModelPropertyModal from './DeviceThingModelPropertyModal.vue';
import {
  addDeviceThingModelFormSchema,
  editDeviceThingModelFormSchema,
  querySchema,
  tableSchema,
} from './schema';

defineOptions({
  name: 'DeviceThingModelManagement',
});

const route = useRoute();

// 从路由参数获取初始平台和产品信息（如果有）
const productId = ref<string>((route.query.productId as string) || '');
const ioTPlatform = ref<string>((route.query.ioTPlatform as string) || '');

const formOptions: VbenFormProps = {
  schema: querySchema.value,
  initialValues: {
    ioTPlatform: route.query.ioTPlatform
      ? String(route.query.ioTPlatform)
      : undefined,
    ioTPlatformProductId: route.query.productId
      ? String(route.query.productId)
      : undefined,
  },
  submitOnChange: false,
  handleValuesChange: async (values, changedFields) => {
    // 平台变化时，清空产品并更新状态
    if (changedFields.includes('ioTPlatform') && values.ioTPlatform) {
      ioTPlatform.value = String(values.ioTPlatform);
      if (gridApi?.formApi) {
        await gridApi.formApi.setValues({
          ioTPlatformProductId: undefined,
        });
      }
      productId.value = '';
    }

    // 产品变化时，更新 productId 并刷新列表
    if (changedFields.includes('ioTPlatformProductId')) {
      productId.value = values.ioTPlatformProductId
        ? String(values.ioTPlatformProductId)
        : '';

      setTimeout(async () => {
        if (gridApi && gridApi.reload) {
          try {
            // 使用最新表单值触发查询，确保搜索关键字等一起传递
            const latestValues = await gridApi.formApi.getValues();
            await gridApi.reload(latestValues);
          } catch (error) {
            console.error('重新加载设备端物模型列表时出错:', error);
          }
        }
      }, 100);
    }
  },
  // 点击搜索按钮时触发
  handleSubmit: async (values) => {
    if (gridApi && gridApi.reload) {
      try {
        await gridApi.reload(values);
      } catch (error) {
        console.error('搜索设备端物模型列表失败:', error);
      }
    }
  },
};

const gridOptions: VxeGridProps<any> = {
  checkboxConfig: {
    highlight: true,
    labelField: 'deviceModelName',
  },
  columns: tableSchema.value,
  height: 'auto',
  keepSource: true,
  pagerConfig: {},
  toolbarConfig: {
    custom: true,
  },
  customConfig: {
    storage: true,
  },
  proxyConfig: {
    ajax: {
      query: async ({ page }, formValues) => {
        // 始终以最新的表单值为准，确保搜索关键字等字段不会丢失
        const latestFormValues =
          formValues ||
          (gridApi && gridApi.formApi ? await gridApi.formApi.getValues() : {});

        // 优先使用表单值，如果没有则使用响应式变量
        const currentPlatform =
          latestFormValues?.ioTPlatform || ioTPlatform.value;
        const currentProductId =
          latestFormValues?.ioTPlatformProductId || productId.value;

        try {
          const { data } = await postDeviceThingModelManagementPageAsync({
            // 使用 JSON Body 传参，按需附加过滤条件
            body: {
              pageIndex: page.currentPage,
              pageSize: page.pageSize,
              ...(currentPlatform && {
                ioTPlatform:
                  typeof currentPlatform === 'string'
                    ? Number.parseInt(currentPlatform)
                    : currentPlatform,
              }),
              ...(currentProductId && {
                ioTPlatformProductId: String(currentProductId),
              }),
              ...(latestFormValues?.SearchKeyWords && {
                searchKeyWords: latestFormValues.SearchKeyWords,
              }),
            },
          });

          return data || { items: [], totalCount: 0 };
        } catch (error) {
          console.error('查询设备端物模型列表失败:', error);
          return {
            items: [],
            totalCount: 0,
          };
        }
      },
    },
  },
};

const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });

const editRow: Record<string, any> = ref({});

// 属性管理弹窗（使用独立组件）
const [PropertyModal, propertyModalApi] = useVbenModal({
  connectedComponent: DeviceThingModelPropertyModal,
});

// 指令管理弹窗（使用独立组件）
const [CommandModal, commandModalApi] = useVbenModal({
  connectedComponent: DeviceThingModelCommandModal,
});

const [ThingModelModal, thingModelModalApi] = useVbenModal({
  draggable: true,
  footer: true,
  showCancelButton: true,
  showConfirmButton: true,
  onConfirm: submit,
  onBeforeClose: () => {
    return true;
  },
  onOpenChange: (isOpen: boolean) => {
    if (isOpen && editRow.value.id) {
      // 编辑模式下，模态框打开后设置表单值
      nextTick(() => {
        const values: any = { ...editRow.value };
        // 确保平台类型与下拉框值类型一致（通常为字符串）
        if (values.ioTPlatform !== undefined && values.ioTPlatform !== null) {
          values.ioTPlatform = String(values.ioTPlatform);
        }
        editFormApi.setValues(values);
      });
    }
  },
  onCancel: () => {
    thingModelModalApi.close();
  },
});

const [AddForm, addFormApi] = useVbenForm({
  collapsed: false,
  commonConfig: {
    labelWidth: 110,
    componentProps: {
      class: 'w-4/5',
    },
  },
  layout: 'horizontal',
  schema: addDeviceThingModelFormSchema.value,
  showCollapseButton: false,
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});

const [EditForm, editFormApi] = useVbenForm({
  collapsed: false,
  commonConfig: {
    labelWidth: 110,
    componentProps: {
      class: 'w-4/5',
    },
  },
  layout: 'horizontal',
  schema: editDeviceThingModelFormSchema.value,
  showCollapseButton: false,
  showDefaultActions: false,
  wrapperClass: 'grid-cols-2',
});

// 函数脚本测试弹窗
const [TestScriptModal, testScriptModalApi] = useVbenModal({
  draggable: true,
  footer: true,
  showCancelButton: true,
  showConfirmButton: true,
  confirmText: '函数测试',
  onConfirm: submitTestScript,
  onBeforeClose: () => {
    return true;
  },
  onCancel: () => {
    testScriptModalApi.close();
  },
});

// 函数脚本测试表单
const [TestScriptForm, testScriptFormApi] = useVbenForm({
  collapsed: false,
  commonConfig: {
    labelWidth: 110,
    componentProps: {
      class: 'w-4/5',
    },
  },
  layout: 'horizontal',
  schema: [
    {
      component: 'Input',
      fieldName: 'functionName',
      label: '函数名称',
      rules: z.preprocess(
        (v) => (v == null ? '' : v),
        z.string().min(1, $t('common.required')),
      ),
      componentProps: {
        placeholder: `${$t('common.pleaseInput')}函数名称`,
      },
    },
    {
      component: 'Textarea',
      fieldName: 'functionCode',
      label: '函数代码',
      rules: z.preprocess(
        (v) => (v == null ? '' : v),
        z.string().min(1, $t('common.required')),
      ),
      componentProps: {
        rows: 8,
        placeholder: `${$t('common.pleaseInput')}函数代码`,
      },
    },
    {
      component: 'Textarea',
      fieldName: 'parameters',
      label: '函数参数（JSON格式）',
      defaultValue:
        '{"0103000000104406":"010320420400004385ACFD4147865241CDCB63000004EF42AFC7AE00000000408000009AAA"}',
      componentProps: {
        rows: 6,
        placeholder:
          '请输入函数参数，JSON格式，例如：{"key1": "value1", "key2": "value2"}',
      },
    },
  ],
  showCollapseButton: false,
  showDefaultActions: false,
  wrapperClass: 'grid-cols-1',
});

// 测试结果
const testResult = ref<string>('');

// 当前测试关联的设备端物模型信息（可选）
const testDeviceThingModelId = ref<string>('');
const testDeviceModelName = ref<string>('');

// 新增 / 编辑提交
async function submit() {
  const isEdit = !!editRow.value.id;
  const formApi = isEdit ? editFormApi : addFormApi;
  const api = isEdit
    ? postDeviceThingModelManagementUpdateAsync
    : postDeviceThingModelManagementCreateAsync;

  const { valid } = await formApi.validate();
  if (!valid) return;

  const formValues = await formApi.getValues();

  // 表单中已经包含 ioTPlatform / ioTPlatformProductId，不再强制从查询条件取
  const fetchParams: any = {
    ...formValues,
    ...(isEdit && { id: editRow.value.id }),
  };

  try {
    const resp = await api({ body: fetchParams });
    if (resp.data) {
      Message.success(
        isEdit ? $t('common.editSuccess') : $t('common.addSuccess'),
      );
      thingModelModalApi.close();
      editRow.value = {};
      // 提交成功后，使用当前查询表单的最新参数刷新列表，确保搜索条件等不会丢失
      if (gridApi && gridApi.reload && gridApi.formApi) {
        const latestValues = await gridApi.formApi.getValues();
        await gridApi.reload(latestValues);
      }
    } else {
      Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
    }
  } catch (error) {
    console.error('提交设备端物模型失败:', error);
    Message.error(isEdit ? $t('common.editFail') : $t('common.addFail'));
  }
}

async function onEdit(record: any) {
  // 如果已启用函数解析，禁止编辑
  if (record.functionAnalysisFlag === true) {
    Message.warning('已启用函数解析的数据不允许编辑');
    return;
  }
  editRow.value = record;
  thingModelModalApi.open();
}

// 打开属性管理
async function openPropertyModal(record: any) {
  editRow.value = record;
  propertyModalApi.setData({
    deviceThingModelId: record.id,
    deviceModelName: record.deviceModelName,
    ioTPlatform: record.ioTPlatform,
    ioTPlatformProductId: record.ioTPlatformProductId,
  });
  propertyModalApi.open();
}

// 打开指令管理
async function openCommandModal(record: any) {
  editRow.value = record;
  commandModalApi.setData({
    deviceThingModelId: record.id,
    deviceModelName: record.deviceModelName,
  });
  commandModalApi.open();
}

const openAddModal = async () => {
  editRow.value = {};
  thingModelModalApi.open();
};

// 打开函数脚本测试弹窗
function openTestScriptModal(record?: any) {
  // 工具栏点击：不关心物模型Id/名称
  if (record && record.id) {
    testDeviceThingModelId.value = record.id;
    testDeviceModelName.value = record.deviceModelName || '';
  } else {
    testDeviceThingModelId.value = '';
    testDeviceModelName.value = '';
  }
  testScriptFormApi.resetForm();
  testResult.value = '';
  testScriptModalApi.open();
}

// 函数构建并打开测试弹窗
async function buildAndOpenTestScript(record: any) {
  if (!record.id) {
    Message.warning('设备端物模型ID不存在');
    return;
  }

  // 如果解析启用为 true，禁止构建函数
  if (record.functionAnalysisFlag === true) {
    Message.warning('解析启用状态下不允许构建函数');
    return;
  }

  try {
    const resp =
      await postDeviceThingModelManagementBuildAnalysisScriptByIdAsync({
        body: { id: record.id },
      });

    console.log('函数构建接口返回:', resp.data);

    // 先通过统一的方法打开弹窗（与工具栏按钮保持一致，并携带物模型信息）
    openTestScriptModal(record);

    // 等待弹窗和表单渲染完成后再回填数据
    await nextTick();
    await testScriptFormApi.setValues({
      functionName: resp.data?.functionName || '',
      functionCode: resp.data?.functionCode || '',
      parameters: '', // 参数需要手动输入
    });

    Message.success('函数构建成功');
  } catch (error) {
    console.error('函数构建失败:', error);
    Message.error('函数构建失败');
  }
}

// 解析启用 / 禁用解析
async function enableAnalysisScript(record: any) {
  if (!record.id) {
    Message.warning('设备端物模型ID不存在');
    return;
  }

  try {
    const isEnabled = record.functionAnalysisFlag === true;

    const resp =
      await postDeviceThingModelManagementUpdateAnalysisScriptByIdAsync({
        query: {
          id: record.id,
        },
      });

    if (resp.data) {
      Message.success(isEnabled ? '禁用解析成功' : '启用解析成功');
      // 刷新列表，确保状态立即更新
      if (gridApi && gridApi.reload) {
        await gridApi.reload();
      }
    } else {
      Message.error(isEnabled ? '禁用解析失败' : '启用解析失败');
    }
  } catch (error) {
    console.error('解析启用失败:', error);
    Message.error('解析状态更新失败');
  }
}

// 提交函数脚本测试
async function submitTestScript() {
  const { valid } = await testScriptFormApi.validate();
  if (!valid) return;

  const formValues = await testScriptFormApi.getValues();

  // 解析 parameters JSON 字符串
  let parameters: any = null;
  if (formValues.parameters) {
    try {
      parameters = JSON.parse(formValues.parameters);
    } catch {
      Message.error('函数参数格式错误，请输入有效的JSON格式');
      return;
    }
  }

  const fetchParams: any = {
    functionName: formValues.functionName,
    functionCode: formValues.functionCode,
    ...(parameters && { parameters }),
  };

  try {
    const resp = await postDeviceThingModelManagementMessageAnalysisTestAsync({
      body: fetchParams,
    });

    // 将结果格式化为JSON字符串显示
    testResult.value = JSON.stringify(resp.data || {}, null, 2);
    Message.success('测试执行成功');
  } catch (error) {
    console.error('函数脚本测试失败:', error);
    testResult.value = `测试失败: ${error instanceof Error ? error.message : String(error)}`;
    Message.error('函数脚本测试失败');
  }
}

// 更新函数脚本到设备端物模型
async function updateFunctionScript() {
  if (!testDeviceThingModelId.value) {
    Message.warning('当前未关联具体设备端物模型，无法更新函数');
    return;
  }

  const { valid } = await testScriptFormApi.validate();
  if (!valid) return;

  const formValues = await testScriptFormApi.getValues();

  try {
    const resp = await postDeviceThingModelManagementBuildAnalysisScriptAsync({
      body: {
        id: testDeviceThingModelId.value,
        scriptName: formValues.functionName,
        functionScript: formValues.functionCode,
      },
    });

    if (resp.data) {
      Message.success('更新函数成功');
    } else {
      Message.error('更新函数失败');
    }
  } catch (error) {
    console.error('更新函数失败:', error);
    Message.error('更新函数失败');
  }
}

// 删除
async function onDel(record: any) {
  try {
    const resp = await postDeviceThingModelManagementDeleteAsync({
      body: { id: record.id },
    });
    if (resp.data) {
      Message.success($t('common.deleteSuccess'));
      gridApi.reload();
    } else {
      Message.error($t('common.deleteFail'));
    }
  } catch (error) {
    console.error('删除设备端物模型失败:', error);
    Message.error($t('common.deleteFail'));
  }
}

// 页面初始化时，自动加载一次列表数据（无产品ID也允许加载）
onMounted(async () => {
  await nextTick();
  setTimeout(async () => {
    if (!gridApi || !gridApi.reload) return;

    try {
      // 先把路由参数（如果有）同步到查询表单
      const formValues = await gridApi.formApi.getValues();
      const newValues: any = { ...formValues };

      if (route.query.ioTPlatform && !formValues.ioTPlatform) {
        newValues.ioTPlatform = route.query.ioTPlatform;
      }
      if (route.query.productId && !formValues.ioTPlatformProductId) {
        newValues.ioTPlatformProductId = route.query.productId;
      }

      if (
        newValues.ioTPlatform !== formValues.ioTPlatform ||
        newValues.ioTPlatformProductId !== formValues.ioTPlatformProductId
      ) {
        await gridApi.formApi.setValues(newValues);
        await nextTick();
      }

      // 无论是否有产品ID，都加载一次列表数据
      await gridApi.reload(newValues);
    } catch (error) {
      console.error('初始化加载设备端物模型列表失败:', error);
    }
  }, 300);
});
</script>

<template>
  <Page auto-content-height>
    <Grid>
      <template #toolbar-actions>
        <TableAction :actions="[
          {
            label: $t('common.add'),
            type: 'primary',
            icon: 'ant-design:plus-outlined',
            onClick: openAddModal.bind(null),
            auth: ['AbpIdentity.Users.Create'],
          },
          {
            label: '函数脚本测试',
            type: 'default',
            icon: 'ant-design:code-outlined',
            onClick: openTestScriptModal,
            auth: ['AbpIdentity.Users.Create'],
          },
        ]" />
      </template>

      <!-- 解析启用列 -->
      <template #functionAnalysisFlag="{ row }">
        <component :is="h(Tag, { color: row.functionAnalysisFlag ? 'green' : 'red' }, () =>
          row.functionAnalysisFlag ? '是' : '否',
        )
          " />
      </template>

      <template #action="{ row }">
        <TableAction :actions="[
          {
            label: $t('common.edit'),
            type: 'link',
            size: 'small',
            auth: ['AbpIdentity.Users.Update'],
            disabled: row.functionAnalysisFlag === true,
            onClick: onEdit.bind(null, row),
          },
          {
            label: '属性管理',
            type: 'link',
            size: 'small',
            auth: ['AbpIdentity.Users.Update'],
            onClick: openPropertyModal.bind(null, row),
          },
          {
            label: '指令管理',
            type: 'link',
            size: 'small',
            auth: ['AbpIdentity.Users.Update'],
            onClick: openCommandModal.bind(null, row),
          },
        ]" :drop-down-actions="[
            {
              label: row.functionAnalysisFlag ? '禁用解析' : '启用解析',
              type: 'input',
              size: 'small',
              auth: ['AbpIdentity.Users.Update'],
              style: row.functionAnalysisFlag
                ? { color: '#ff4d4f' } // 红色：禁用解析
                : { color: '#52c41a' }, // 绿色：启用解析
              popConfirm: {
                title: row.functionAnalysisFlag
                  ? '确定要禁用该设备端物模型的解析吗？'
                  : '确定要启用该设备端物模型的解析吗？',
                confirm: enableAnalysisScript.bind(null, row),
              },
            },
            {
              label: '函数构建',
              type: 'link',
              size: 'small',
              auth: ['AbpIdentity.Users.Update'],
              disabled: row.functionAnalysisFlag === true,
              popConfirm: {
                title: '确定要为该设备端物模型执行函数构建吗？',
                confirm: buildAndOpenTestScript.bind(null, row),
              },
            },
            {
              label: $t('common.delete'),
              type: 'link',
              size: 'small',
              auth: ['AbpIdentity.Users.Delete'],
              style: { color: '#ff4d4f' },
              popConfirm: {
                title: $t('common.askConfirmDelete'),
                confirm: onDel.bind(null, row),
              },
            },
          ]" />
      </template>
    </Grid>

    <!-- 属性管理弹窗（独立组件） -->
    <PropertyModal />

    <!-- 指令管理弹窗（独立组件） -->
    <CommandModal />

    <ThingModelModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
      <component :is="editRow.id ? EditForm : AddForm" />
    </ThingModelModal>

    <!-- 函数脚本测试弹窗 -->
    <TestScriptModal title="函数脚本测试（函数代码中的函数名要与函数名称表单值一致）" class="w-[900px]">
      <div v-if="testDeviceModelName" class="mb-2 text-base font-semibold">
        设备端物模型：{{ testDeviceModelName }}
      </div>
      <TestScriptForm />
      <div v-if="testResult" class="mt-4">
        <div class="mb-2 font-semibold">测试结果：</div>
        <pre class="max-h-96 overflow-auto rounded border bg-gray-50 p-4 text-sm">{{ testResult }}</pre>
      </div>
      <template #center-footer>
        <Button v-if="testDeviceThingModelId" type="primary" @click="updateFunctionScript">
          更新函数
        </Button>
      </template>
    </TestScriptModal>
  </Page>
</template>
