package com.njcn.msgpush.module.push.client.sender.impl.apppush;

import cn.hutool.core.util.StrUtil;
import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.Settings;
import com.getui.push.v2.sdk.dto.req.message.PushChannel;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.AndroidDTO;
import com.getui.push.v2.sdk.dto.req.message.android.GTNotification;
import com.getui.push.v2.sdk.dto.req.message.android.ThirdNotification;
import com.getui.push.v2.sdk.dto.req.message.android.Ups;
import com.getui.push.v2.sdk.dto.req.message.ios.Alert;
import com.getui.push.v2.sdk.dto.req.message.ios.Aps;
import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO;
import com.njcn.msgpush.module.push.client.sender.AppPushSender;
import com.njcn.msgpush.module.push.client.sender.SendResult;
import com.njcn.msgpush.module.push.client.sender.Sender;
import com.njcn.msgpush.module.push.client.setting.impl.UniPushAppPushSetting;
import com.njcn.msgpush.module.push.dal.dataobject.message.MessageRecordDO;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;

@Slf4j
public class UniPushAppPushSender implements AppPushSender {

    private final Sender sender;

    private PushApi pushApi;

    public UniPushAppPushSender(UniPushAppPushSetting uniPushAppPushSetting, Sender sender) {
        this.sender = sender;
        try {
            GtApiConfiguration gtApiConfiguration = new GtApiConfiguration();
            gtApiConfiguration.setAppId(uniPushAppPushSetting.getAppId());
            gtApiConfiguration.setAppKey(uniPushAppPushSetting.getAppKey());
            gtApiConfiguration.setMasterSecret(uniPushAppPushSetting.getMasterSecret());
            // 使用配置的 API 地址，如果未配置则使用默认地址
            String apiUrl = uniPushAppPushSetting.getApiUrl();
            if (StrUtil.isNotBlank(apiUrl)) {
                gtApiConfiguration.setDomain(apiUrl);
            } else {
                gtApiConfiguration.setDomain("https://restapi.getui.com/v2/");
            }
            ApiHelper apiHelper = ApiHelper.build(gtApiConfiguration);
            this.pushApi = apiHelper.creatApi(PushApi.class);
        } catch (Exception e) {
            log.error("UniPush 客户端初始化失败", e);
            this.pushApi = null;
        }
    }

    @Override
    public SendResult appPush(MessageRecordDO message) {
        if (pushApi == null) {
            return SendResult.configInvalid("当前服务商 APP 推送渠道初始化失败");
        }
        try {
            LocalDateTime now = LocalDateTime.now();
            long start = now.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            PushDTO<Audience> pushDTO = this.buildPushDTO(message.getTitle(), message.getContent());
            Audience audience = new Audience();
            audience.addCid(message.getReceiver());
            pushDTO.setAudience(audience);

            ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
            LocalDateTime end = LocalDateTime.now();
            int costTime = (int) (end.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() - start);
            message.setSendTime(now);
            message.setCostTime(costTime);

            if (apiResult.isSuccess()) {
                // UniPush 同步接口返回成功时，当前平台将其视为已受理。
                return SendResult.accepted(now, costTime, null);
            }
            // 个推原始错误码在这里统一映射为平台错误码和中文错误信息。
            return this.sender.buildFailureResult(
                    message,
                    String.valueOf(apiResult.getCode()),
                    apiResult.getMsg(),
                    "THIRD_PARTY_CALL_FAILED",
                    "第三方服务调用失败",
                    false
            );
        } catch (Exception e) {
            log.error("UniPush 推送失败", e);
            return this.sender.buildCallFailedResult("第三方服务调用失败");
        }
    }

    private PushDTO<Audience> buildPushDTO(String title, String content) {
        PushDTO<Audience> pushDTO = new PushDTO<>();
        pushDTO.setRequestId(String.valueOf(System.currentTimeMillis()));

        Settings settings = new Settings();
        settings.setTtl(3600000);
        pushDTO.setSettings(settings);

        // 创建 PushMessage，设置透传消息（可选）
        PushMessage pushMessage = new PushMessage();
        pushMessage.setTransmission("{\"title\":\"" + title + "\",\"body\":\"" + content + "\"}");

        // 在线推送 - 使用 GTNotification
        GTNotification gtNotification = new GTNotification();
        gtNotification.setTitle(title);
        gtNotification.setBody(content);
        gtNotification.setClickType("startapp");
        pushMessage.setNotification(gtNotification);

        pushDTO.setPushMessage(pushMessage);

        // 创建 PushChannel 用于配置各平台的通知
        PushChannel pushChannel = new PushChannel();

        // Android 离线推送配置 - 使用 ThirdNotification
        AndroidDTO androidDTO = new AndroidDTO();
        Ups ups = new Ups();
        ThirdNotification thirdNotification = new ThirdNotification();
        thirdNotification.setTitle(title);
        thirdNotification.setBody(content);
        thirdNotification.setClickType("startapp");
        ups.setNotification(thirdNotification);
        androidDTO.setUps(ups);
        pushChannel.setAndroid(androidDTO);

        // iOS 通知配置
        IosDTO iosDTO = new IosDTO();
        Aps aps = new Aps();
        Alert alert = new Alert();
        alert.setTitle(title);
        alert.setBody(content);
        aps.setAlert(alert);
        aps.setSound("default");
        aps.setContentAvailable(0);
        iosDTO.setAps(aps);
        pushChannel.setIos(iosDTO);

        // 将 PushChannel 设置到 PushDTO 中
        pushDTO.setPushChannel(pushChannel);

        return pushDTO;
    }
}
