package com.neusoft.smart.pos.member.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.neusoft.smart.pos.dto.member.request.CreateMemberLevelRequest;
import com.neusoft.smart.pos.dto.member.response.MemberLevelResponse;
import com.neusoft.smart.pos.framework.dto.ResponseData;
import com.neusoft.smart.pos.member.dto.MemberLevelPolicyResponse;
import com.neusoft.smart.pos.member.dto.request.*;
import com.neusoft.smart.pos.member.service.MemberLevelPolicyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

@Api(value = "会员等级管理restful接口", description = "会员等级管理restful接口")
@RestController
@Validated
public class MemberLevelController {
    @Autowired
    MemberLevelPolicyService memberLevelPolicyService;

    @ApiOperation(value = "get member level list")
    @GetMapping("/member-level")
    public ResponseData<List<MemberLevelResponse>> getMemberLevelList(@Validated @ModelAttribute GetMemberLevelRequest request) {
        GetMemberLevelPolicyRequest policyRequest = new GetMemberLevelPolicyRequest();
        policyRequest.setOrg(request.getOrg());
        policyRequest.setStore(request.getStore());
        List<MemberLevelPolicyResponse> policyResponses = memberLevelPolicyService.selectMemberLevelPolicyList(policyRequest);
        List<MemberLevelResponse> responseList = new ArrayList<>();
        for (MemberLevelPolicyResponse policyResponse:policyResponses
             ) {
            MemberLevelResponse response = new MemberLevelResponse();
            response.setId(policyResponse.getId());
            response.setLevel(policyResponse.getLevelNumber());
            response.setName(policyResponse.getLevelName());
            response.setDiscount(getDiscountFromPolicy(policyResponse.getBonusTable()));
            response.setRequiredRechargeAmount(getRechargeAmountFromPolicy(policyResponse.getCondition()));
            responseList.add(response);
        }
        return new ResponseData<>(responseList);
    }

    @ApiOperation(value = "get member level")
    @GetMapping("/member-level/{id}")
    public ResponseData<MemberLevelResponse> getMemberLevel(@PathVariable Integer id) {
        MemberLevelPolicyResponse policyResponse = memberLevelPolicyService.selectMemberLevelPolicyById(id);
        MemberLevelResponse response = new MemberLevelResponse();
        response.setId(policyResponse.getId());
        response.setLevel(policyResponse.getLevelNumber());
        response.setName(policyResponse.getLevelName());
        response.setDiscount(getDiscountFromPolicy(policyResponse.getBonusTable()));
        response.setRequiredRechargeAmount(getRechargeAmountFromPolicy(policyResponse.getCondition()));
        return new ResponseData<>(response);
    }

    @ApiOperation(value = "create member level")
    @PostMapping("/member-level")
    public ResponseData<MemberLevelResponse> createMemberLevel(@RequestBody CreateMemberLevelRequest request) {
        CreateMemberLevelPolicyRequest policyRequest = new CreateMemberLevelPolicyRequest();
        policyRequest.setBonusArray(genPolicyByDiscount(request.getDiscount()));
        policyRequest.setCondition(genPolicyByRechargeAmount(request.getRequiredRechargeAmount()));
        policyRequest.setLevelName(request.getName());
        policyRequest.setLevelNumber(request.getLevel());
        policyRequest.setOrg(request.getOrg());
        policyRequest.setStore(request.getStore());
        MemberLevelPolicyResponse policyResponse = memberLevelPolicyService.insertOrUpdateMemberLevelPolicy(policyRequest);
        MemberLevelResponse response = new MemberLevelResponse();
        response.setId(policyResponse.getId());
        response.setLevel(policyResponse.getLevelNumber());
        response.setName(policyResponse.getLevelName());
        response.setDiscount(getDiscountFromPolicy(policyResponse.getBonusTable()));
        response.setRequiredRechargeAmount(getRechargeAmountFromPolicy(policyResponse.getCondition()));
        return new ResponseData<>(response);
    }

    @ApiOperation(value = "update member level")
    @PatchMapping("/member-level/{id}")
    public ResponseData<MemberLevelResponse> updateMemberLevel(@PathVariable Integer id, @RequestBody UpdateMemberLevelRequest request) {
        UpdateMemberLevelPolicyRequest policyRequest = new UpdateMemberLevelPolicyRequest();
        policyRequest.setBonusArray(genPolicyByDiscount(request.getDiscount()));
        policyRequest.setCondition(genPolicyByRechargeAmount(request.getRequiredRechargeAmount()));
        policyRequest.setLevelName(request.getName());
        MemberLevelPolicyResponse policyResponse = memberLevelPolicyService.updateMemberLevelPolicy(id, policyRequest);
        MemberLevelResponse response = new MemberLevelResponse();
        response.setId(policyResponse.getId());
        response.setLevel(policyResponse.getLevelNumber());
        response.setName(policyResponse.getLevelName());
        response.setDiscount(getDiscountFromPolicy(policyResponse.getBonusTable()));
        response.setRequiredRechargeAmount(getRechargeAmountFromPolicy(policyResponse.getCondition()));
        return new ResponseData<>(response);
    }

    @ApiOperation(value = "delete member level")
    @DeleteMapping("/member-level")
    public ResponseData<Integer> deleteMemberLevel(@RequestBody DeleteMemberLevelRequest request) {
        DeleteMemberLevelPolicyRequest policyRequest = new DeleteMemberLevelPolicyRequest();
        policyRequest.setLevel(request.getLevel());
        policyRequest.setOrg(request.getOrg());
        policyRequest.setStore(request.getStore());
        memberLevelPolicyService.deleteMemberPolicyLevel(policyRequest);
        return new ResponseData<>(1);
    }

    private BigDecimal getDiscountFromPolicy(String policyString) {
        JSONObject table = JSONObject.parseObject(policyString);
        JSONObject jsonObject = JSONObject.parseObject(table.getString("0"));
        String val = jsonObject.getJSONObject("para").getString("discount");
        return BigDecimal.valueOf(Long.parseLong(val));
    }

    private BigDecimal getRechargeAmountFromPolicy(String policyString) {
        JSONObject jsonObject = JSONObject.parseObject(policyString);
        String val = jsonObject.getJSONObject("condition").getString("rechargeAmount");
        return BigDecimal.valueOf(Long.parseLong(val)).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
    }

    private String genPolicyByDiscount(BigDecimal discount) {
        Integer val = (int)(discount.doubleValue()*10);
        JSONObject table = new JSONObject();
        JSONObject jsonObject = new JSONObject();
        JSONObject para = new JSONObject();
        para.put("discount", val);
        jsonObject.put("para", para);
        jsonObject.put("type", 0);
        table.put("0", jsonObject);
        return table.toJSONString();
    }

    private String genPolicyByRechargeAmount(BigDecimal reChargeAmount) {
        Integer val = reChargeAmount.intValue();
        JSONObject jsonObject = new JSONObject();
        JSONObject condition = new JSONObject();
        condition.put("rechargeAmount", val);
        jsonObject.put("condition", condition);
        jsonObject.put("type", 0);
        return jsonObject.toJSONString();
    }
}
