<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue';
import { message } from 'ant-design-vue';

import { useRequest } from '@/hooks/request';
import { t } from '@/i18n';
import {
  gatewayLinkDelete,
  gatewayLinkGetList,
  gatewayLinkList,
  gatewayLinkProtocolReset,
  gatewayLinkUpdate,
  getDictTypeData,
  postProtocolCandidatesList,
} from '@/api';
import { DictCode } from '@/constants';

import type { FormInstance } from 'ant-design-vue';
import type { Rule } from 'ant-design-vue/es/form';
import type { Key } from 'ant-design-vue/es/table/interface';
import type {
  AgreementData,
  AgreementForm,
  InterfaceData,
  OptionItem,
  ProtocolItem,
  ProtocolsItem,
  RegisterGatewayForm,
  UseGuideStepItemProps,
  VerificationAgreement,
} from '@/types';

const { handleRequest } = useRequest();

const props = defineProps<UseGuideStepItemProps<RegisterGatewayForm>>();

const interfaceData = ref<InterfaceData[]>([]);
const value2 = ref('2');

const agreementForm = reactive<AgreementForm>({
  baudRate: 0,
  dataBit: '',
  parityBit: '',
  stopBit: '',
  readTimeout: 0,
  nextDataReadDelay: 0,
  nextRoundDataReadDelay: 0,
});

const open = ref<boolean>(false);
const open1 = ref<boolean>(false);
const open2 = ref<boolean>(false);

const agreementData = ref<AgreementData[]>([]);

const baudRatelist = ref<OptionItem<number>[]>([]);

const protocolList = ref<ProtocolItem[]>([]);

const formRef = ref<FormInstance>();

const protocolsItem = reactive<AgreementData>({
  protocolType: '',
  station: '',
  name: '',
  protocolName: '',
  dev: '',
  dataSendInterval: 0,
  highFreqSendInterval: 0,
  protocolId: 0,
  isStandard: '0',
});

let agreementIndex: number;

let protocolItem: ProtocolItem;

let agreementId: number;
let interfaceIndex: number;
let advancedIndex: number;

let verificationAgreement: VerificationAgreement[] = [];

let data: ProtocolsItem[] = [];

const columns = [
  {
    title: t('setupProtocol.protocolType'),
    dataIndex: 'protocolType',
    key: 'protocolType',
    width: 170,
  },
  {
    title: t('registerGateway.stationNumber'),
    dataIndex: 'station',
    key: 'station',
  },
  {
    title: t('registerGateway.electricMeter'),
    dataIndex: 'name',
    key: 'name',
  },
  {
    title: t('registerGateway.communicationProtocol'),
    key: 'protocolName',
    dataIndex: 'protocolName',
    width: 220,
  },
  {
    title: t('registerGateway.associatedEquipment'),
    key: 'dev',
    dataIndex: 'dev',
  },
  {
    title: t('common.operation'),
    key: 'action',
  },
];

const protocolColumns = [
  {
    title: t('setupProtocol.protocolType'),
    dataIndex: 'protocolName',
    key: 'protocolName',
  },
  {
    title: t('registerGateway.agreementNumber'),
    dataIndex: 'protocolNumber',
    key: 'protocolNumber',
  },
  {
    title: t('setupProtocol.protocolName'),
    dataIndex: 'deviceType',
    key: 'deviceType',
  },
];

const options2 = ref([
  {
    value: '1',
    payload: t('registerGateway.platformAgreement'),
  },
  {
    value: '2',
    payload: t('registerGateway.proprietaryProtocol'),
  },
]);

const postGetList = () => {
  handleRequest(async () => {
    interfaceData.value = await gatewayLinkGetList(props.form.id);
  });
};

const addDelete = (value: number) => {
  handleRequest(async () => {
    await gatewayLinkDelete(value);
    postGetList();
  });
};

const addSlave = () => {
  agreementData.value.push({
    protocolType: '',
    station: '',
    name: '',
    protocolName: '',
    dev: '',
    dataSendInterval: 0,
    highFreqSendInterval: 0,
    protocolId: 0,
    isStandard: '0',
  });
};

const bindingAgreement = () => {
  data = [];
  formRef.value
    ?.validate()
    .then(() => {
      handleRequest(async () => {
        if (agreementData.value.length) {
          agreementData.value.forEach((item) => {
            const { protocolId, station, isStandard, dataSendInterval, highFreqSendInterval } = item;
            data.push({
              protocolId,
              station,
              isStandard,
              dataSendInterval,
              highFreqSendInterval,
            });
          });

          await gatewayLinkProtocolReset({
            linkId: agreementId,
            protocols: data,
          });

          const { linkName, interfaceId, gatewayId, bindState } = interfaceData.value[interfaceIndex];
          const { dataBit, parityBit, stopBit, baudRate, readTimeout, nextDataReadDelay, nextRoundDataReadDelay } =
            agreementForm;

          await gatewayLinkUpdate({
            id: agreementId,
            linkName,
            interfaceId,
            gatewayId,
            bindState,
            dataBit,
            parityBit,
            stopBit,
            baudRate,
            readTimeout,
            nextDataReadDelay,
            nextRoundDataReadDelay,
          });

          open.value = false;

          postGetList();
        } else {
          message.warning(t('registerGateway.prompt'));
        }
      });
    })
    .catch(() => {});
};

const deleteAgreement = (value: number) => {
  agreementData.value.splice(value, 1);
};

const advancedSettings = (value: AgreementData, index: number) => {
  advancedIndex = index;
  const { dataSendInterval, highFreqSendInterval } = value;
  protocolsItem.dataSendInterval = dataSendInterval;
  protocolsItem.highFreqSendInterval = highFreqSendInterval;
  open2.value = true;
};

const replaceAgreement = (value: number) => {
  agreementIndex = value;
  open1.value = true;

  handleRequest(async () => {
    const { records } = await postProtocolCandidatesList(
      {
        pageIndex: 1,
        pageSize: 10,
      },
      props.form.id,
    );
    protocolList.value = records;
  });
};

const rules1: Record<string, Rule[]> = {
  dataSendInterval: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  highFreqSendInterval: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
};

const rules: Record<string, Rule[]> = {
  baudRate: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  dataBit: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  parityBit: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  stopBit: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  readTimeout: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  nextDataReadDelay: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
  nextRoundDataReadDelay: [{ required: true, message: t('common.cannotEmpty'), trigger: 'change' }],
};

const rowSelectedChange = (selectedRowKeys: Key[], selectedRows: ProtocolItem[]) => {
  protocolItem = selectedRows[0];
};

// 根据条件显示背景
const interfaceShow = (value: string) => {
  return value === 'LAN' ? 'background-color: rgba(54, 207, 201, 1);' : 'background-color: rgba(89, 126, 247, 1);';
};

// 根据条件显示编辑/绑定文本
const textShow = (value: number) => {
  return value === 0 ? t('common.binding') : t('common.revise');
};

// 显示绑定/编辑弹框
const addEditor = (value: number, index: number, bindState: number) => {
  agreementId = value;
  interfaceIndex = index;
  open.value = true;
  Object.assign(agreementForm, interfaceData.value[index]);
  agreementData.value = [];
  handleRequest(async () => {
    const data = await getDictTypeData({
      dictCode: DictCode.BaudRate,
    });

    if (data.length) {
      baudRatelist.value = data[0].dictTypeDataList.map((item) => ({
        value: item.dictValueId,
        label: item.dictValue,
      }));
      agreementForm.baudRate = Number(data[0].dictTypeDataList[0].dictValue);
    }

    if (bindState === 1) {
      verificationAgreement = await gatewayLinkList(agreementId);

      verificationAgreement.forEach((item) => {
        const { protocolType, station, protocolName, dataSendInterval, highFreqSendInterval, protocolId, isStandard } =
          item;
        agreementData.value.push({
          name: '',
          dev: '',
          protocolType,
          station: String(station),
          protocolName,
          dataSendInterval,
          highFreqSendInterval,
          protocolId,
          isStandard: String(isStandard),
        });
      });
    }
  });
};

const handleOk = () => {
  agreementData.value[advancedIndex].dataSendInterval = protocolsItem.dataSendInterval;
  agreementData.value[advancedIndex].highFreqSendInterval = protocolsItem.highFreqSendInterval;
  open2.value = false;
};

const handleOk1 = () => {
  const { protocolName, baudRate, dataSendInterval, highFreqSendInterval, id } = protocolItem;
  agreementData.value[agreementIndex] = {
    protocolType: String(baudRate),
    station: '',
    name: '',
    protocolName,
    dev: '',
    dataSendInterval,
    highFreqSendInterval,
    protocolId: id,
    isStandard: '0',
  };
  open1.value = false;
};

onMounted(() => {
  postGetList();
});
</script>

<template>
  <div>
    <div class="use-guide-title">{{ $t('registerGateway.bindingAgreement') }}</div>
    <div class="use-guide-description">文本描述！！！</div>
    <div class="interface-content">
      <ABadge v-for="(item, index) in interfaceData" :key="item.id">
        <template #count v-if="item.bindState === 1">
          <img referrerpolicy="no-referrer" src="@/assets/img/checked.png" />
        </template>
        <AFlex class="interface-div" justify="flex-start" align="center">
          <ARow style="width: 100%">
            <ACol :span="14">
              <AFlex justify="flex-start" align="center">
                <AFlex
                  class="interface-div1"
                  :style="interfaceShow(item.interfaceType)"
                  justify="center"
                  align="center"
                >
                  <span class="interface-div1-span">{{ item.interfaceType }}</span>
                </AFlex>

                <div class="interface-div2">{{ item.linkName }}</div>
              </AFlex>
            </ACol>
            <ACol :span="10">
              <AFlex justify="flex-end" align="center">
                <AButton
                  style="margin-top: 10px; color: #1890ff"
                  type="link"
                  danger
                  @click="addEditor(item.id, index, item.bindState)"
                  >{{ textShow(item.bindState) }}</AButton
                >
                <AButton style="margin-top: 8px; margin-right: 10px" type="link" danger @click="addDelete(item.id)">{{
                  $t('common.delete')
                }}</AButton>
              </AFlex>
            </ACol>
          </ARow>
        </AFlex>
      </ABadge>
    </div>
    <AModal
      v-model:open="open"
      :closable="false"
      width="1100px"
      :footer="null"
      :mask-closable="false"
      :keyboard="false"
    >
      <AForm
        ref="formRef"
        class="protocol-class"
        :model="agreementForm"
        label-align="left"
        layout="vertical"
        :rules="rules"
        :wrapper-col="{ span: 21 }"
      >
        <ARow style="margin-top: 40px">
          <ACol :span="6">
            <AFormItem :label="$t('setupProtocol.baudRate')" name="baudRate">
              <ASelect
                v-model:value="agreementForm.baudRate"
                class="protocol-select"
                :placeholder="$t('common.plzSelect')"
              >
                <ASelectOption v-for="item in baudRatelist" :key="item.value" :value="item.label">
                  {{ item.label }}
                </ASelectOption>
              </ASelect>
            </AFormItem>
          </ACol>
          <ACol :span="6">
            <AFormItem :label="$t('setupProtocol.dataBit')" name="dataBit">
              <ARadioGroup v-model:value="agreementForm.dataBit">
                <ARadio :value="5">5</ARadio>
                <ARadio :value="6">6</ARadio>
                <ARadio :value="7">7</ARadio>
                <ARadio :value="8">8</ARadio>
              </ARadioGroup>
            </AFormItem>
          </ACol>
          <ACol :span="6">
            <AFormItem :label="$t('setupProtocol.stopBit')" name="stopBit">
              <ARadioGroup v-model:value="agreementForm.stopBit">
                <ARadio value="1">1</ARadio>
                <ARadio value="1.5">1.5</ARadio>
                <ARadio value="2">2</ARadio>
              </ARadioGroup>
            </AFormItem>
          </ACol>
          <ACol :span="6">
            <AFormItem :label="$t('setupProtocol.parityBit')" name="parityBit">
              <ARadioGroup v-model:value="agreementForm.parityBit">
                <ARadio value="N">N</ARadio>
                <ARadio value="O">O</ARadio>
                <ARadio value="E">E</ARadio>
              </ARadioGroup>
            </AFormItem>
          </ACol>
        </ARow>
        <ARow>
          <ACol :span="6">
            <AFormItem :label="$t('setupProtocol.readTimeout')" name="readTimeout">
              <AInputNumber v-model:value="agreementForm.readTimeout">
                <template #addonAfter>ms</template>
              </AInputNumber>
            </AFormItem>
          </ACol>
          <ACol :span="6">
            <AFormItem :label="$t('registerGateway.nextDelayExtraction')" name="nextDataReadDelay">
              <AInputNumber v-model:value="agreementForm.nextDataReadDelay">
                <template #addonAfter>ms</template>
              </AInputNumber>
            </AFormItem>
          </ACol>
          <ACol :span="6">
            <AFormItem :label="$t('registerGateway.nextRoundDelayExtraction')" name="nextRoundDataReadDelay">
              <AInputNumber v-model:value="agreementForm.nextRoundDataReadDelay">
                <template #addonAfter>ms</template>
              </AInputNumber>
            </AFormItem>
          </ACol>
        </ARow>
      </AForm>
      <ATable :columns="columns" :data-source="agreementData" :pagination="false" :scroll="{ y: 350 }">
        <template #bodyCell="{ column, record, index }">
          <template v-if="column.key === 'protocolType'">
            <AInput disabled v-model:value="record.protocolType" />
          </template>
          <template v-else-if="column.key === 'station'">
            <AInput v-model:value="record.station" />
          </template>
          <template v-else-if="column.key === 'name'">
            <AInput disabled v-model:value="record.name" />
          </template>
          <template v-else-if="column.key === 'protocolName'">
            <AInputSearch disabled v-model:value="record.protocolName">
              <template #enterButton>
                <AButton style="color: #32bac0" @click="replaceAgreement(index)">{{
                  $t('registerGateway.renegotiationAgreement')
                }}</AButton>
              </template>
            </AInputSearch>
          </template>
          <template v-else-if="column.key === 'action'">
            <AButton @click="advancedSettings(record as AgreementData, index)">{{ $t('common.settings') }}</AButton>
            <AButton @click="deleteAgreement(index)">{{ $t('common.delete') }}</AButton>
          </template>
        </template>
      </ATable>

      <AFlex justify="space-between">
        <div class="but-text" @click="addSlave">
          <span>{{ $t('registerGateway.addStation') }}</span>
        </div>
        <div style="margin-top: 24px">
          <AButton class="off-but" @click="open = false">{{ $t('common.turnOff') }}</AButton>
          <AButton type="primary" @click="bindingAgreement">{{ $t('common.save') }}</AButton>
        </div>
      </AFlex>
    </AModal>

    <AModal
      v-model:open="open1"
      :title="$t('registerGateway.renegotiationAgreement')"
      :ok-text="$t('common.confirm')"
      :cancel-text="$t('common.cancel')"
      width="1100px"
      @ok="handleOk1"
      :mask-closable="false"
      :keyboard="false"
    >
      <ARow style="margin-top: 40px; margin-bottom: 10px">
        <ACol :span="12">
          <ASegmented class="agreement-segmented" v-model:value="value2" :options="options2">
            <template #label="{ payload }">
              <div style="padding: 4px">
                <div>{{ payload }}</div>
              </div>
            </template>
          </ASegmented>
        </ACol>
        <ACol :span="12">
          <AFlex justify="flex-end">
            <AInput style="width: 50%" :placeholder="$t('registerGateway.pleaseProtocolName')" />
          </AFlex>
        </ACol>
      </ARow>
      <ATable
        :row-selection="{
          type: 'radio',
          onChange: rowSelectedChange,
        }"
        row-key="id"
        :columns="protocolColumns"
        :data-source="protocolList"
      />
    </AModal>

    <AModal
      v-model:open="open2"
      :title="$t('registerGateway.advancedSettingsAgreement')"
      :ok-text="$t('common.confirm')"
      :cancel-text="$t('common.cancel')"
      width="500px"
      @ok="handleOk"
      :mask-closable="false"
      :keyboard="false"
    >
      <AForm :model="protocolsItem" label-align="left" layout="vertical" :rules="rules1" :wrapper-col="{ span: 20 }">
        <ARow style="margin-top: 40px">
          <ACol :span="12">
            <AFormItem :label="$t('registerGateway.dataReportingFrequency')" name="dataSendInterval">
              <AInput v-model:value="protocolsItem.dataSendInterval" placeholder="Basic usage" /> </AFormItem
          ></ACol>
          <ACol :span="12"
            ><AFormItem :label="$t('registerGateway.highDataFrequencyReportingFrequency')" name="highFreqSendInterval">
              <AInput v-model:value="protocolsItem.highFreqSendInterval" placeholder="Basic usage" /> </AFormItem
          ></ACol>
        </ARow>
      </AForm>
    </AModal>
  </div>
</template>

<style lang="scss" scoped>
.interface-content {
  width: 570px;
  margin-top: 24px;
}

.interface-div {
  width: 457px;
  height: 67px;
  margin-bottom: 14px;
  background-color: rgb(240 240 240 / 100%);
  border-radius: 8px;
}

.interface-div1 {
  width: 48px;
  height: 48px;
  margin-left: 20px;
  border-radius: 4px;
}

.interface-div1-span {
  font-size: 16px;
  font-style: normal;
  font-weight: 400;
  line-height: 18px;
  color: rgb(255 255 255 / 97%);
}

.interface-div2 {
  margin-left: 20px;
  font-size: 16px;
  font-style: normal;
  font-weight: 500;
  line-height: 17px;
  color: var(--antd-color-text-secondary);
  text-align: left;
}

.protocol-class .ant-form-item {
  margin-bottom: 15px !important;
}

.dev-list {
  display: flex;
  align-items: center; /* 垂直居中 */
  justify-content: center; /* 水平居中 */
  width: 80px;
  height: 32px;
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 22px;
  color: #333;
  text-align: left;
  background-color: #e1f5f6;
}

.but-text {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 108px;
  height: 32px;
  margin-top: 8px;
  font-size: 14px;
  font-style: normal;
  font-weight: 400;
  line-height: 24px;
  color: #32bac0;
  text-align: left;
  cursor: pointer;
}

.off-but {
  margin-right: 16px;
  color: #32bac0;
  border-color: #32bac0;
}
</style>
