package com.njcn.msgpush.module.push.controller.admin.channel;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.msgpush.framework.common.pojo.CommonResult;
import com.njcn.msgpush.module.push.client.factory.MessageProviderFactory;
import com.njcn.msgpush.module.push.client.factory.impl.AliyunProviderFactory;
import com.njcn.msgpush.module.push.client.factory.impl.TelecomProviderFactory;
import com.njcn.msgpush.module.push.client.factory.impl.UniPushProviderFactory;
import com.njcn.msgpush.module.push.controller.admin.channel.vo.ChannelProviderConfigReqVO;
import com.njcn.msgpush.module.push.dal.dataobject.channel.ChannelProviderConfigDO;
import com.njcn.msgpush.module.push.enums.ProviderTypeEnum;
import com.njcn.msgpush.module.push.service.channel.ChannelProviderConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

import static com.njcn.msgpush.framework.common.pojo.CommonResult.success;


@Tag(name = "管理后台 - 渠道服务商")
@Slf4j
@Validated
@RestController
@RequestMapping("/push/channel")
public class ChannelProviderConfigController {

    @Autowired
    private ChannelProviderConfigService channelProviderConfigService;

    @Autowired
    @Qualifier("messageProviderFactoryMap")
    private Map<String, MessageProviderFactory> messageProviderFactoryMap;

    @PostMapping("/page")
    @Operation(summary = "分页查询渠道服务商列表")
    @PreAuthorize("@ss.hasPermission('push:channel:page')")
    public CommonResult<Page<ChannelProviderConfigDO>> pageChannelProviderConfig(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
        return success(channelProviderConfigService.getPage(reqVO));
    }

    @PostMapping("/add")
    @Operation(summary = "新增渠道服务商")
    @PreAuthorize("@ss.hasPermission('push:channel:add')")
    public CommonResult<Boolean> add(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
        boolean res = channelProviderConfigService.save(BeanUtil.copyProperties(reqVO, ChannelProviderConfigDO.class));
        return success(res);
    }

    @PostMapping("/update")
    @Operation(summary = "更新渠道服务商")
    @PreAuthorize("@ss.hasPermission('push:channel:update')")
    public CommonResult<Boolean> update(@Validated @RequestBody ChannelProviderConfigReqVO reqVO) {
        boolean res = channelProviderConfigService.updateById(BeanUtil.copyProperties(reqVO, ChannelProviderConfigDO.class));
        return success(res);
    }

    @PostMapping("/delete")
    @Operation(summary = "删除渠道服务商")
    @PreAuthorize("@ss.hasPermission('push:channel:delete')")
    @Parameter(name = "ids", description = "id列表", required = true)
    public CommonResult<Boolean> delete(@RequestParam("ids") List<String> ids) {
        boolean res = channelProviderConfigService.removeBatchByIds(ids);
        return success(res);
    }

    @GetMapping("/toggle")
    @Operation(summary = "启用/禁用渠道服务商")
    @PreAuthorize("@ss.hasPermission('push:channel:toggle')")
    @Parameter(name = "id", description = "id", required = true)
    public CommonResult<Void> toggleEnableChannelProvider(@RequestParam("id") String id) {
        ChannelProviderConfigDO channelProviderConfigDO = channelProviderConfigService.toggleEnableField(id);

        if (channelProviderConfigDO.getEnabled() == 1) {
            registerProviderBean(channelProviderConfigDO.getProviderType());
        } else {
            removeProviderBean(channelProviderConfigDO.getProviderType());
        }
        return success(null);
    }

    /**
     * 添加指定providerType服务商对应的bean
     *
     * @param providerType 服务商类型，例如：aliyun\telecom\UniPush
     */
    public void registerProviderBean(String providerType) {
        switch (ProviderTypeEnum.getByCode(providerType)) {
            case ALIYUN: {
                messageProviderFactoryMap.put(ProviderTypeEnum.ALIYUN.getCode(), new AliyunProviderFactory());
            }
            break;
            case TELECOM: {
                messageProviderFactoryMap.put(ProviderTypeEnum.TELECOM.getCode(), new TelecomProviderFactory());
            }
            break;
            case UNIPUSH: {
                messageProviderFactoryMap.put(ProviderTypeEnum.UNIPUSH.getCode(), new UniPushProviderFactory());
            }
            break;
            default:
                throw new IllegalArgumentException("该" + providerType + "服务商暂不支持");
        }
    }

    /**
     * 移除指定providerType服务商对应的bean
     *
     * @param providerType 服务商类型，例如：aliyun\telecom\UniPush
     */
    public void removeProviderBean(String providerType) {
        messageProviderFactoryMap.remove(providerType);
    }
}
