package com.cpop.core.strategy.login;

import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.loginInfo.MiniUserLoginInfo;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.CpopAuthenticationException;
import com.cpop.core.base.table.SysUser;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.row.DbChain;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowKey;
import org.springframework.stereotype.Component;

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

/**
 * @author DB
 * @createTime 2023/11/08 10:34
 * @description 小程序登陆
 */
@Component
public class MiniLoginStrategy implements LoginStrategy {

    /**
     * @descriptions 获取登陆用户信息
     * @author DB
     * @date 2023/11/08 9:34
     * @param sysUser 系统用户
     * @param credentials 登陆相关凭着
     * @return: com.cpop.core.base.entity.LoginUser
     */
    @Override
    public LoginUser getLoginUserInfo(SysUser sysUser, Map<String, Object> credentials) {
        MiniUserLoginInfo loginInfo = BeanUtils.mapToClass(sysUser, MiniUserLoginInfo.class);
        loginInfo.setUserId(sysUser.getId());
        //已经注册过有用户信息
        if (credentials == null){
            //构建用户信息
            Row row = DbChain.table("cp_mini_user")
                    .select("cmu.id","cmu.open_id","cmu.app_id","cmu.user_id","cmu.brand_id","cmu.nick_name","cmu.avatar","cmu.source_type")
                    .from("cp_mini_user").as("cmu")
                    .where("cmu.user_id = ?", loginInfo.getUserId())
                    .and("cmu.is_delete = 0")
                    .one();
            loginInfo.setOpenId(row.getString("openId"))
                    .setAppId(row.getString("appId"))
                    .setUserId(row.getString("userId"))
                    .setBrandId(row.getString("brandId"))
                    .setNickName(row.getString("nickName"))
                    .setAvatar(row.getString("avatar"))
                    .setId(row.getString("id"))
                    .setSourceType(SourceType.valueOf(row.getString("sourceType")));
        } else {
            SourceType sourceType;
            //校验用户来源
            if (credentials.get("sourceType") == null) {
                loginInfo.setSourceType(SourceType.COMMON);
            } else if (SourceType.JAMBOX == SourceType.valueOf(credentials.get("sourceType").toString())){
                //来源自果酱
                sourceType = SourceType.JAMBOX;
                //查询果酱用户
                changeJamboxUser(loginInfo, credentials ,sourceType);
            } else {
                //先用通用
                loginInfo.setSourceType(SourceType.COMMON);
            }
        }
        LoginUser loginUser = new LoginUser(loginInfo, loginInfo.getId(), null);
        loginUser.setUserId(sysUser.getId())
                .setUserType(UserType.MINI_USER)
                .setUserName(sysUser.getUserName())
                .setLoginTime(System.currentTimeMillis())
                .setStatus(sysUser.getStatus());
        return loginUser;
    }

    /**
     * @descriptions 获取果酱小程序用户信息
     * @author DB
     * @date 2023/10/25 14:53
     * @param loginInfo 用户信息
     * @param credentials 请求参数
     * @param sourceType 来源类型
     * @return: void
     */
    private void changeJamboxUser(MiniUserLoginInfo loginInfo, Map<String, Object> credentials, SourceType sourceType) {
        //获取品牌表
        Row brand = DbChain.table("cp_sys_brand")
                .select("csb.id", "csb.is_open_sharing")
                .from("cp_sys_brand").as("csb")
                .leftJoin("cp_j_brand_extend").as("cjbe").on("cjbe.brand_id = csb.id")
                .and("cjbe.brand_cloud_id = ?", credentials.get("brandId"))
                .one();
        if (brand == null) {
            throw new CpopAuthenticationException("用户登陆失败,果酱品牌暂未录入系统");
        }
        //构建用户信息
        Row row = DbChain.table("cp_mini_user")
                .select("cmu.id","cmu.open_id","cmu.app_id","cmu.brand_id","cmu.nick_name","cmu.avatar","cmu.source_type")
                .from("cp_mini_user").as("cmu")
                .leftJoin("cp_j_brand_extend").as("cjbe").on("cjbe.brand_id = cmu.brand_id")
                .where("cmu.app_id = ?",credentials.get("appId"))
                .and("cjbe.brand_cloud_id = ?",credentials.get("brandId"))
                .and("cmu.open_id = ?",credentials.get("openId"))
                //用户来源
                .and("cmu.source_type = ?",sourceType.toString())
                .and("cmu.is_delete = 0")
                .one();
        //保存小程序用户信息
        LocalDateTime now = LocalDateTime.now();
        if (row == null) {
            Row miniUser = Row.ofKey(RowKey.SNOW_FLAKE_ID);
            miniUser.set("open_id", credentials.get("openId"))
                    .set("app_id", credentials.get("appId"))
                    .set("brand_id", brand.getString("id"))
                    .set("nick_name", credentials.get("nickName"))
                    .set("avatar", credentials.get("avatar"))
                    .set("source_type", sourceType.toString())
                    .set("create_time", now)
                    .set("update_time", now)
                    .set("create_user_id", 1)
                    .set("update_user_id", 1);
            int save = Db.insert("cp_mini_user", miniUser);
            //插入中间表
            Row miniMidUser = new Row();
            miniMidUser.set("user_id", loginInfo.getUserId())
                    .set("mini_id",miniUser.getString("id"))
                    .set("create_time", now)
                    .set("update_time", now)
                    .set("create_user_id", 1)
                    .set("update_user_id", 1);
            Db.insert("cp_mini_user_mid_sys", miniMidUser);
            if (save > 0) {
                loginInfo.setOpenId((String) credentials.get("openId"))
                        .setAppId((String) credentials.get("appId"))
                        .setBrandId(brand.getString("id"))
                        .setNickName((String) credentials.get("nickName"))
                        .setAvatar((String) credentials.get("avatar"))
                        .setId(miniUser.getString("id"))
                        .setSourceType(sourceType);
            }
        } else {
            //查询中间表
            long count = DbChain.table("cp_mini_user_mid_sys")
                    .where("mini_id = ?", row.getString("id"))
                    .and("user_id = ?", loginInfo.getUserId())
                    .count();
            if (count == 0) {
                //插入中间表
                Row miniMidUser = new Row();
                miniMidUser.set("user_id", loginInfo.getUserId())
                        .set("mini_id", row.getString("id"))
                        .set("create_time", now)
                        .set("update_time", now)
                        .set("create_user_id", 1)
                        .set("update_user_id", 1);
                Db.insert("cp_mini_user_mid_sys", miniMidUser);
            }
            loginInfo.setOpenId(row.getString("openId"))
                    .setAppId(row.getString("appId"))
                    .setBrandId(row.getString("brandId"))
                    .setNickName(row.getString("nickName"))
                    .setAvatar(row.getString("avatar"))
                    .setId(row.getString("id"))
                    .setSourceType(sourceType);
        }
    }
}
