package com.fizz.business.service.impl;

import com.fizz.business.comm.iot.S7WriteClient;
import com.fizz.business.form.OpcBatchWriteDataForm;
import com.fizz.business.form.OpcWriteDataForm;
import com.fizz.business.service.OpcDataService;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

/**
 * OPC 数据读写服务实现类
 *
 * 说明：
 * 1) 写入逻辑已切换为 iot-communication（S7）
 * 2) 读取逻辑仍保留在原 OPC 体系（不在本类中）
 */
@Slf4j
@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "iot.communication", name = "enabled", havingValue = "true")
public class OpcDataServiceImpl implements OpcDataService {

    private final S7WriteClient s7WriteClient;

    @Override
    public boolean writeData(OpcWriteDataForm form) {
        try (S7PLC s7PLC = s7WriteClient.newClient()) {
            writeByGuessType(s7PLC, form.getFieldName(), form.getValue());
            return true;
        } catch (Exception e) {
            log.error("写入 S7 数据异常，address={}, value={}", form.getFieldName(), form.getValue(), e);
            return false;
        }
    }

    @Override
    public boolean batchWriteData(OpcBatchWriteDataForm form) {
        try (S7PLC s7PLC = s7WriteClient.newClient()) {
            for (OpcWriteDataForm item : form.getDataList()) {
                writeByGuessType(s7PLC, item.getFieldName(), item.getValue());
            }
            return true;
        } catch (Exception e) {
            log.error("批量写入 S7 数据异常", e);
            return false;
        }
    }

    private void writeByGuessType(S7PLC s7PLC, String address, Object value) {
        if (value == null) {
            throw new IllegalArgumentException("写入值不能为空");
        }
        if (address == null || address.trim().isEmpty()) {
            throw new IllegalArgumentException("写入地址不能为空");
        }

        if (value instanceof Boolean) {
            s7PLC.writeBoolean(address, (Boolean) value);
            return;
        }
        if (value instanceof Byte) {
            s7PLC.writeByte(address, (Byte) value);
            return;
        }
        if (value instanceof Short) {
            s7PLC.writeInt16(address, (Short) value);
            return;
        }
        if (value instanceof Integer) {
            s7PLC.writeInt32(address, (Integer) value);
            return;
        }
        if (value instanceof Long) {
            s7PLC.writeInt64(address, (Long) value);
            return;
        }
        if (value instanceof Float) {
            s7PLC.writeFloat32(address, (Float) value);
            return;
        }
        if (value instanceof Double) {
            s7PLC.writeFloat64(address, (Double) value);
            return;
        }
        if (value instanceof byte[]) {
            s7PLC.writeByte(address, (byte[]) value);
            return;
        }

        // 兜底按字符串写入
        s7PLC.writeString(address, String.valueOf(value));
    }
}
