package org.dromara.app;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.business.IMemberBusiness;
import com.wzj.soopin.member.convert.AccountBillConvert;
import com.wzj.soopin.member.convert.MemberAccountConvert;
import com.wzj.soopin.member.convert.MemberBankConvert;
import com.wzj.soopin.member.convert.MemberConvert;
import com.wzj.soopin.member.domain.bo.AccountBillBO;
import com.wzj.soopin.member.domain.bo.MemberBO;
import com.wzj.soopin.member.domain.bo.MemberBankBO;
import com.wzj.soopin.member.domain.po.AccountBill;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.po.MemberAccount;
import com.wzj.soopin.member.domain.po.MemberBank;
import com.wzj.soopin.member.domain.vo.AccountBillVO;
import com.wzj.soopin.member.domain.vo.MemberAccountVO;
import com.wzj.soopin.member.domain.vo.MemberBankVO;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.service.IMemberAccountService;
import com.wzj.soopin.member.service.IMemberBankService;
import com.wzj.soopin.member.service.IMemberService;
import com.wzj.soopin.transaction.convert.ChargeConvert;
import com.wzj.soopin.transaction.convert.WithdrawConvert;
import com.wzj.soopin.transaction.domain.bo.ChargeBO;
import com.wzj.soopin.transaction.domain.bo.WithdrawBO;
import com.wzj.soopin.transaction.enums.WithdrawType;
import com.wzj.soopin.transaction.service.IAccountBillService;
import com.wzj.soopin.transaction.service.IChargeService;
import com.wzj.soopin.transaction.service.IWithdrawService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.domain.model.SocialLoginBody;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.ratelimiter.annotation.RateLimiter;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.SocialUtils;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/app/member")
@Tag(name = "会员管理")
@RequiredArgsConstructor
public class AppMemberController {
    private final IMemberBusiness memberBusiness;

    private final IMemberService service;

    private final MemberConvert convert;

    private final MemberAccountConvert accountConvert;

    private final IMemberAccountService accountService;

    private final IAccountBillService accountBillService;

    private final AccountBillConvert accountBillConvert;
    private final SocialProperties socialProperties;

    private final IMemberBankService memberBankService;
    private final MemberBankConvert memberBankConvert;
    private final IChargeService chargeService;
    private final ChargeConvert chargeConvert;

    private final IWithdrawService withdrawService;
    private final WithdrawConvert withdrawConvert;

    @Operation(summary = "获取会员账户信息详细信息")
    @GetMapping(value = "/info")
    public R<MemberVO> getInfo(Long memberId) {
        //获取用户信息
        if(memberId==null){
            LoginUser loginUser = LoginHelper.getLoginUser();
            if (loginUser == null) {
                throw new ServiceException("用户未登录");
            }
            memberId = loginUser.getUserId();
        }
        return R.ok(service.getMemberInfo(memberId));
    }

    @Operation(summary = "获取会员账户表详细信息")
    @GetMapping(value = "/account")
    public R<MemberAccountVO> accountInfo() {
        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        return R.ok(accountConvert.toVO(accountService.getMemberAccount(loginUser.getUserId())));
    }

    @Operation(summary = "查询账单")
    @PostMapping("/bank")
    public R<Page<MemberBankVO>> list(@RequestBody MemberBankBO bo,
                                      @RequestBody Page<MemberBank> page) {
        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        Long memberId = loginUser.getUserId();
        bo.setMemberId(memberId);
        Page<MemberBank> memberPage = memberBankService.page(page, bo.toWrapper());
        return R.ok(memberBankConvert.toVO(memberPage));
    }

    @Operation(summary = "查询账单")
    @PostMapping("/bills")
    public R<Page<AccountBillVO>> list(@RequestBody AccountBillBO bo,
                                       @RequestBody Page<AccountBill> page) {
        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        Long memberId = loginUser.getUserId();
        //根据会员获取账户信息
        MemberAccount memberAccount = accountService.getMemberAccount(memberId);
        if (memberAccount == null) {
            throw new ServiceException("用户未绑定账户");
        }
        bo.setAccountId(memberAccount.getId());
        Page<AccountBill> memberPage = accountBillService.page(page, bo.toWrapper());
        return R.ok(accountBillConvert.toVO(memberPage));
    }


    @Operation(summary = "绑定推广人")
    @PostMapping("/bind/spread")
    public R<AuthToken> bindSpread(@RequestBody MemberBO bo) {

        memberBusiness.bindSpread(bo);
        return R.ok();
    }

    @Operation(summary = "绑定微信")
    @PostMapping("/bind/wechat")
    public R<AuthToken> bindWechat(@RequestBody SocialLoginBody loginBody) {

        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        Long memberId = loginUser.getUserId();

        ValidatorUtils.validate(loginBody);
        AuthResponse<AuthUser> response = SocialUtils.loginAuth(
            loginBody.getSource(), loginBody.getSocialCode(),
            loginBody.getSocialState(), socialProperties);
        if (!response.ok()) {
            throw new ServiceException(response.getMsg());
        }

        AuthUser authUserData = response.getData();

        String unionId=authUserData.getToken().getUnionId();
        Member member = Member.builder().id(memberId).openId(unionId).build();
        service.updateById(member);
//        更新用户的微信信息
//            返回给前端
        return R.ok(authUserData.getToken());
    }

    @Operation(summary = "充值")
    @Log(title = "新增 ", businessType = BusinessType.INSERT)
    @PostMapping("/charge")
    public R charge(@RequestBody ChargeBO bo) {

        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        Long memberId = loginUser.getUserId();
        bo.setMemberId(memberId);

        return R.ok(chargeService.charge(chargeConvert.toPo(bo)));
    }
    @Operation(summary = "提现")
    @Log(title = "提现 ", businessType = BusinessType.INSERT)
    @PostMapping("/withdraw")
    public R withdraw(@RequestBody WithdrawBO bo) {
        //获取用户信息
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("用户未登录");
        }
        Long memberId = loginUser.getUserId();
        bo.setMemberId(memberId);
        bo.setType(WithdrawType.WALLET.getCode());
        return R.ok(withdrawService.withdrawWallet(withdrawConvert.toPo(bo)));
    }



    @RateLimiter(key = "#phonenumber", time = 60, count = 1)
    @GetMapping("/sms/code")
    @Operation(summary = "给当前登录会员的手机号发送短信验证码")
    public R smsCode(@RequestParam String templateId) {
        service.smsCode(templateId);
        return R.ok();
    }



    @Operation(summary = "用户注销")
    @Log(title = "用户注销 ", businessType = BusinessType.UPDATE)
    @PostMapping("/revoked")
    public R revoked(@RequestParam String smsCode) {
        service.revoked(smsCode);
        return R.ok();
    }



}
