<script setup lang="ts">
import { nextTick, ref } from 'vue';

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

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

import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
  getCommonGetSelectList,
  postDeviceThingModelManagementCommandCreateAsync,
  postDeviceThingModelManagementCommandDeleteAsync,
  postDeviceThingModelManagementCommandFindByIdAsync,
  postDeviceThingModelManagementCommandPageAsync,
  postDeviceThingModelManagementCommandUpdateAsync,
  postDeviceThingModelManagementPropertyPageAsync,
  postDeviceThingModelManagementUpdateCommandStatusByIdAsync,
} from '#/api-client';
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';

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

const deviceThingModelId = ref<string>('');
const deviceModelName = ref<string>('');

const editRow: Record<string, any> = ref({});
const propertyOptions = ref<Array<{ label: string; value: string }>>([]);
const DEFAULT_COMMAND_TYPE = '1';
const OPERATE_COMMAND_TYPE = '2';

function normalizeCommandType(value: unknown): string {
  if (value === null || value === undefined || value === '') {
    return DEFAULT_COMMAND_TYPE;
  }
  return String(value);
}

function isOperateCommandType(value: unknown): boolean {
  return normalizeCommandType(value) === OPERATE_COMMAND_TYPE;
}

// 指令列表
const [Grid, gridApi] = useVbenVxeGrid({
  formOptions: {
    schema: [],
    showDefaultActions: false,
  },
  gridOptions: {
    columns: [
      {
        field: 'commandName',
        title: '指令名称',
        minWidth: 160,
        showOverflow: 'tooltip',
      },
      {
        field: 'issueCommand',
        title: '下发指令',
        minWidth: 200,
        showOverflow: 'tooltip',
      },
      {
        field: 'propertyArray',
        title: '平台端属性标识符集合',
        minWidth: 200,
        showOverflow: 'tooltip',
        formatter: ({ cellValue }: { cellValue: any }) => {
          if (Array.isArray(cellValue)) {
            return cellValue.join(', ');
          }
          if (typeof cellValue === 'string') {
            try {
              const parsed = JSON.parse(cellValue);
              if (Array.isArray(parsed)) {
                return parsed.join(', ');
              }
            } catch {
              return cellValue;
            }
          }
          return cellValue || '-';
        },
      },
      {
        field: 'isEnable',
        title: '状态',
        width: 90,
        align: 'center',
        slots: { default: 'isEnable' },
      },
      {
        field: 'action',
        title: $t('common.action'),
        width: 190,
        fixed: 'right',
        slots: { default: 'action' },
      },
    ],
    height: 400,
    pagerConfig: {},
    toolbarConfig: {
      custom: true,
    },
    proxyConfig: {
      ajax: {
        query: async ({ page }) => {
          if (!deviceThingModelId.value) {
            return { items: [], totalCount: 0 };
          }
          const { data } = await postDeviceThingModelManagementCommandPageAsync(
            {
              body: {
                pageIndex: page.currentPage,
                pageSize: page.pageSize,
                deviceThingModelId: deviceThingModelId.value,
              },
            },
          );
          return data || { items: [], totalCount: 0 };
        },
      },
    },
  },
});

// 指令新增/编辑弹窗
const [CommandFormModal, commandFormModalApi] = useVbenModal({
  draggable: true,
  footer: true,
  showCancelButton: true,
  showConfirmButton: true,
  onConfirm: submitCommand,
  onBeforeClose: () => {
    return true;
  },
  onOpenChange: async (isOpen: boolean) => {
    if (isOpen) {
      // 加载当前设备端物模型的属性列表，用于选择属性标识符
      await loadPropertyOptions();
      if (editRow.value.id) {
        // 编辑模式下，加载指令详情
        nextTick(async () => {
          try {
            const { data } =
              await postDeviceThingModelManagementCommandFindByIdAsync({
                body: { id: editRow.value.id },
              });
            if (data) {
              const values: any = { ...data };
              values.commandType = normalizeCommandType(values.commandType);
              // 处理 propertyArray 字段
              if (values.propertyArray) {
                if (typeof values.propertyArray === 'string') {
                  try {
                    values.propertyArray = JSON.parse(values.propertyArray);
                  } catch {
                    values.propertyArray = [values.propertyArray];
                  }
                }
                if (!Array.isArray(values.propertyArray)) {
                  values.propertyArray = [];
                }
              } else {
                values.propertyArray = [];
              }
              if (!isOperateCommandType(values.commandType)) {
                values.operateCommandType = undefined;
              }
              commandFormApi.setValues(values);
            }
          } catch (error) {
            console.error('加载指令详情失败:', error);
          }
        });
      } else {
        // 新增模式下，清空表单
        commandFormApi.resetForm();
      }
    }
  },
  onCancel: () => {
    commandFormModalApi.close();
  },
});

// 加载属性选项（用于指令的属性标识符选择）
async function loadPropertyOptions() {
  if (!deviceThingModelId.value) {
    return;
  }
  try {
    const { data } = await postDeviceThingModelManagementPropertyPageAsync({
      body: {
        pageIndex: 1,
        pageSize: 1000,
        deviceThingModelId: deviceThingModelId.value,
        isPage: false,
      },
    });
    const items = data?.items || [];
    propertyOptions.value = items.map((item: any) => ({
      label: `${item.standardFieldDisplayName || item.standardFieldName} (${item.standardFieldName})`,
      value: item.ioTPlatformRawFieldName,
    }));
  } catch (error) {
    console.error('加载属性列表失败:', error);
  }
}

// 指令表单
const [CommandForm, commandFormApi] = useVbenForm({
  collapsed: false,
  commonConfig: {
    labelWidth: 140,
    componentProps: {
      class: 'w-4/5',
    },
  },
  layout: 'horizontal',
  schema: [
    {
      component: 'ApiSelect',
      fieldName: 'commandType',
      label: '指令类型',
      defaultValue: DEFAULT_COMMAND_TYPE,
      rules: z.preprocess(
        (v) => normalizeCommandType(v),
        z.string().min(1, '请选择指令类型'),
      ),
      componentProps: {
        api: getCommonGetSelectList,
        params: {
          query: {
            typeName: 'DeviceThingModeCommandTypeEnum',
          },
        },
        labelField: 'value',
        valueField: 'key',
        optionsPropName: 'options',
        immediate: true,
        allowClear: false,
        placeholder: '请选择指令类型',
        afterFetch: (res: any) => {
          if (Array.isArray(res)) {
            return res;
          }
          if (res && Array.isArray(res.items)) {
            return res.items;
          }
          if (res && Array.isArray(res.data)) {
            return res.data;
          }
          return [];
        },
      },
    },
    {
      component: 'InputNumber',
      fieldName: 'operateCommandType',
      label: '操作类型',
      dependencies: {
        triggerFields: ['commandType'],
        show(values: any) {
          return isOperateCommandType(values.commandType);
        },
      },
      componentProps: {
        min: 0,
        precision: 0,
        placeholder: `${$t('common.pleaseInput')}操作类型`,
      },
    },
    {
      component: 'Input',
      fieldName: 'commandName',
      label: '指令名称',
      rules: z.preprocess(
        (v) => (v == null ? '' : v),
        z.string().min(1, $t('common.required')),
      ),
      componentProps: {
        placeholder: `${$t('common.pleaseInput')}指令名称`,
      },
    },
    {
      component: 'Textarea',
      fieldName: 'issueCommand',
      label: '下发指令',
      rules: z.preprocess(
        (v) => (v == null ? '' : v),
        z.string().min(1, $t('common.required')),
      ),
      componentProps: {
        rows: 4,
        placeholder: `${$t('common.pleaseInput')}下发指令（完整的单个下发指令）`,
      },
    },
    {
      component: 'Select',
      fieldName: 'propertyArray',
      label: '属性标识符集合',
      rules: z.preprocess(
        (v) => (v == null ? [] : v),
        z.array(z.string()).min(1, '请至少选择一个属性标识符'),
      ),
      // 使用函数形式，保证 options 能随着 propertyOptions 的变化而更新
      componentProps: () => ({
        mode: 'multiple',
        placeholder: '请选择属性标识符',
        options: propertyOptions.value,
        showSearch: true,
        filterOption: (input: string, option: any) => {
          return String(option.label)
            .toLowerCase()
            .includes(input.toLowerCase());
        },
      }),
    },
  ],
  showCollapseButton: false,
  showDefaultActions: false,
  wrapperClass: 'grid-cols-1',
});

// 打开新增指令弹窗
function openAddCommandModal() {
  editRow.value = {};
  commandFormModalApi.open();
  nextTick(() => {
    commandFormApi.setValues({ commandType: DEFAULT_COMMAND_TYPE });
  });
}

// 打开编辑指令弹窗
function openEditCommandModal(record: any) {
  editRow.value = record;
  commandFormModalApi.open();
}

// 提交指令（新增/编辑）
async function submitCommand() {
  const isEdit = !!editRow.value.id;
  const { valid } = await commandFormApi.validate();
  if (!valid) return;

  const formValues = await commandFormApi.getValues();
  const commandType = normalizeCommandType(formValues.commandType);
  if (
    isOperateCommandType(commandType) &&
    (formValues.operateCommandType === null ||
      formValues.operateCommandType === undefined ||
      formValues.operateCommandType === '')
  ) {
    Message.warning('请选择操作类型');
    return;
  }

  const fetchParams: any = {
    ...formValues,
    commandType,
    ...(isOperateCommandType(commandType)
      ? {
          operateCommandType: Number(formValues.operateCommandType),
        }
      : { operateCommandType: undefined }),
    deviceThingModelId: deviceThingModelId.value,
    // 确保 propertyArray 是数组格式
    propertyArray: Array.isArray(formValues.propertyArray)
      ? formValues.propertyArray
      : (formValues.propertyArray
        ? [formValues.propertyArray]
        : []),
    ...(isEdit && { id: editRow.value.id }),
  };

  try {
    const api = isEdit
      ? postDeviceThingModelManagementCommandUpdateAsync
      : postDeviceThingModelManagementCommandCreateAsync;
    const resp = await api({ body: fetchParams });
    if (resp.data) {
      Message.success(
        isEdit ? $t('common.editSuccess') : $t('common.addSuccess'),
      );
      commandFormModalApi.close();
      editRow.value = {};
      await nextTick();
      if (gridApi && gridApi.reload) {
        await gridApi.reload();
      }
    } 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 onDeleteCommand(record: any) {
  try {
    const resp = await postDeviceThingModelManagementCommandDeleteAsync({
      body: { id: record.id },
    });
    if (resp.data) {
      Message.success($t('common.deleteSuccess'));
      await nextTick();
      if (gridApi && gridApi.reload) {
        await gridApi.reload();
      }
    } else {
      Message.error($t('common.deleteFail'));
    }
  } catch (error) {
    console.error('删除指令失败:', error);
    Message.error($t('common.deleteFail'));
  }
}

// 更新指令启用状态（调用接口，提交参数为 JSON 格式：{ id, isEnable }）
async function onUpdateCommandStatus(record: any) {
  const nextEnable = !record.isEnable;
  const action = nextEnable ? '启用' : '禁用';
  try {
    const resp =
      await postDeviceThingModelManagementUpdateCommandStatusByIdAsync({
        body: { id: record.id, isEnable: nextEnable } as any,
      });
    if (resp.data) {
      Message.success(`${action}成功`);
      await nextTick();
      if (gridApi && gridApi.reload) {
        await gridApi.reload();
      }
    } else {
      Message.error(`${action}失败`);
    }
  } catch (error) {
    console.error(`${action}指令状态失败:`, error);
    Message.error(`${action}失败`);
  }
}

const [Modal, modalApi] = useVbenModal({
  onOpenChange(isOpen: boolean) {
    if (isOpen) {
      const data = modalApi.getData<Record<string, any>>();
      deviceThingModelId.value = data?.deviceThingModelId || '';
      deviceModelName.value = data?.deviceModelName || '';
      // 使用 nextTick 确保 Grid 组件已完全初始化
      nextTick(() => {
        if (gridApi && gridApi.reload) {
          gridApi.reload();
        }
      });
    }
  },
});
</script>

<template>
  <Modal :title="`指令管理 - ${deviceModelName || ''}`" class="w-[900px]">
    <Grid>
      <template #toolbar-actions>
        <TableAction :actions="[
          {
            label: $t('common.add'),
            type: 'primary',
            icon: 'ant-design:plus-outlined',
            onClick: openAddCommandModal,
            auth: ['AbpIdentity.Users.Create'],
          },
        ]" />
      </template>

      <template #isEnable="{ row }">
        <Tag v-if="row.isEnable" color="green">启用</Tag>
        <Tag v-else color="red">禁用</Tag>
      </template>
      <template #action="{ row }">
        <TableAction :actions="[
          {
            label: row.isEnable ? '禁用' : '启用',
            type: 'link',
            size: 'small',
            style: row.isEnable ? { color: '#ff4d4f' } : { color: '#52c41a' },
            onClick: onUpdateCommandStatus.bind(null, row),
          },
          {
            label: $t('common.edit'),
            type: 'link',
            size: 'small',
            auth: ['AbpIdentity.Users.Update'],
            onClick: openEditCommandModal.bind(null, row),
          },
          {
            label: $t('common.delete'),
            icon: 'ant-design:delete-outlined',
            type: 'link',
            size: 'small',
            style: { color: '#ff4d4f' },
            auth: ['AbpIdentity.Users.Delete'],
            popConfirm: {
              title: $t('common.askConfirmDelete'),
              confirm: onDeleteCommand.bind(null, row),
            },
          },
        ]" />
      </template>
    </Grid>

    <!-- 指令新增/编辑弹窗 -->
    <CommandFormModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
      <CommandForm />
    </CommandFormModal>
  </Modal>
</template>
