package com.copy.trade.controller;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.copy.trade.bean.S3Config;
import com.copy.trade.constant.DogeApi;
import com.copy.trade.constant.KafkaTopic;
import com.copy.trade.entity.dto.AccountRiskControlMessage;
import com.copy.trade.entity.dto.CustomerMessage;
import com.copy.trade.entity.form.CustomerForm;
import com.copy.trade.entity.form.TraderQueryForm;
import com.copy.trade.entity.po.Customer;
import com.copy.trade.entity.vo.CustomerVo;
import com.copy.trade.entity.vo.TraderVo;
import com.copy.trade.service.ICustomerService;
import com.copy.trade.util.BeanCopior;
import com.copy.trade.util.DogeContractUtils;
import com.copy.trade.util.FileUtils;
import com.copy.trade.util.OssUtil;
import com.copy.trade.util.WebAssert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author wz
 * @since 2022-11-08
 */
@Api(value = "交易员、学生、用户接口", tags = "关于用户的接口")
@RestController
@RequestMapping("/customer")
public class CustomerController {

	private final Logger log = LoggerFactory.getLogger(CustomerController.class);

    @Value("${doge.host_inner}")
    private String dogeHost;

	@Autowired
	private S3Config s3Config;

	ICustomerService customerServiceImpl;
	
	@Autowired
    private KafkaTemplate kafkaTemplate;
	


	/**
	 * 推荐使用构造器注入
	 * @param customerServiceImpl
	 */
	@Autowired
	CustomerController(ICustomerService customerServiceImpl) {
		this.customerServiceImpl = customerServiceImpl;
	}


	@ApiOperation(value = "查询用户个人信息")
	@GetMapping("/")
	public Customer get(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember){
		Customer customerDB = customerServiceImpl.getByMemberId(authMember.getId());
		if(customerDB == null) {
			try {
				customerServiceImpl.openAccount(authMember);
			} catch (Exception e) {
				log.info("account exist memberId={}", authMember.getId());
			}
			customerDB = customerServiceImpl.getByMemberId(authMember.getId());
		}
		log.info("customerDB={}", customerDB);
		//CustomerVo customerVo = BeanCopior.map(customerDB, CustomerVo.class);
		return customerDB;
	}

	@ApiOperation(value = "开通跟单账户")
	@GetMapping("/open-account")
	public Boolean openAccount(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember){
		return customerServiceImpl.openAccount(authMember);
	}

	@ApiOperation(value = "更新个人信息", notes = "更新个人信息")
	@ApiImplicitParam(name = "customerForm", value = "个人信息表单", required = true, dataTypeClass = CustomerForm.class)
	@PostMapping("/update")
	public Boolean update(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember,@RequestBody @Valid CustomerForm customerForm){
		Customer customerDB = customerServiceImpl.getByMemberId(authMember.getId());
		Boolean updated = false;
		Boolean updateRiskControl = false;
		if(!StringUtils.isBlank(customerForm.getNickName())
		&& !customerForm.getNickName().equals(customerDB.getNickname())){
			customerDB.setNickname(customerForm.getNickName());

			synchronousInformation(authMember.getId() + "", customerDB.getNickname(), customerDB.getAvatar());
			
			updated = true;
		}

		if(!StringUtils.isBlank(customerForm.getDescription())
				&& !customerForm.getDescription().equals(customerDB.getDescription())){
			customerDB.setDescription(customerForm.getDescription());
			updated = true;
		}
		if(customerForm.getAutomaticUnfollow()!=null) {
			customerDB.setAutomaticUnfollow(customerForm.getAutomaticUnfollow());
			updated = true;
		}
		if(customerForm.getMaxLoss()!=null) {
			customerDB.setMaxLoss(customerForm.getMaxLoss());
			updated = true;
			updateRiskControl = true;
		}
		if(customerForm.getMaxProfit()!=null) {
			customerDB.setMaxProfit(customerForm.getMaxProfit());
			updated = true;
			updateRiskControl = true;
		}
		if(!updated){
			return true;
		}
		customerServiceImpl.updateById(customerDB);
		if(updateRiskControl) {
			//发送消息
			AccountRiskControlMessage accountRiskControlMessage = new AccountRiskControlMessage();
			accountRiskControlMessage.setMemberId(authMember.getId());
			accountRiskControlMessage.setLossPercent(customerDB.getMaxLoss());;
			accountRiskControlMessage.setProfitPercent(customerDB.getMaxProfit());
			kafkaTemplate.send(KafkaTopic.FOLLOW_ACCOUNT_PERCENT_CHANGE, JSON.toJSONString(accountRiskControlMessage));
		}
		
		return true;
	}

	@ApiOperation(value = "更新头像", notes = "更新头像")
	@ApiImplicitParam(paramType = "form", name = "avatar", value = "头像文件", dataType = "__file")
	@PostMapping("/update-avatar")
	public String updateAvatar(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember,@ApiParam("avatar") MultipartFile avatar){
		Customer customerDB = customerServiceImpl.getByMemberId(authMember.getId());
		//校验文件是否是图片
		FileUtils.FileInfo  fileInfo = new FileUtils().new FileInfo();
		try{
			fileInfo = FileUtils.getFileInfo(avatar);
		}catch (IOException ioe){
			log.error("校验文件类型异常,异常信息:",ioe);
		}
		WebAssert.hasAuth(fileInfo.getIsPicture(), "chk.avatar.fileType.error");
		//上传头像
		//生成新的文件名
		String uuid = UUID.randomUUID().toString();
		String fileName = uuid + "." + fileInfo.getFileType();
		InputStream inputStream = null;
		try {
			 inputStream = avatar.getInputStream();
			//avatar.transferTo(new File(avatarPath + File.pathSeparator + fileName));
			 fileName = OssUtil.upload(inputStream,fileName,true,s3Config);
		} catch (IOException ioe) {
			log.error("上传图片失败:",ioe);
			WebAssert.throwException("chk.avatar.fileType.error");
		}finally {
			if(inputStream != null){
				try{
					inputStream.close();
				}catch (IOException e){

				}
			}
		}
		//更新用户头像
		customerDB.setAvatar(fileName);
		customerServiceImpl.updateById(customerDB);

		synchronousInformation(authMember.getId() + "", customerDB.getNickname(), customerDB.getAvatar());

		return fileName;
	}

	@ApiOperation(value = "申请成为交易员", notes = "申请成为交易员")
	@GetMapping("/apply-trader")
	public Boolean applyTrader(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember, HttpServletRequest request){
		String authToken = request.getHeader(DogeApi.TOKEN_NAME);
		authMember.setAuthToken(authToken);
		Map<String, String> headers = new HashMap<>();
		if (authToken != null) {
			headers.put(DogeApi.TOKEN_NAME, authToken);
		}
		String cookie = request.getHeader("Cookie");
		if (cookie != null) {
			headers.put("Cookie", cookie);
		}
		return customerServiceImpl.applyTrade(authMember, headers);
	}


	@ApiOperation(value = "交易员列表", notes = "交易员列表")
	@ApiImplicitParam(name = "traderQueryForm",value = "交易员列表查询表单",required = true,dataType = "TraderQueryForm")
	@PostMapping("/trader-list")
	public Page<TraderVo> traderList(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember,@RequestBody TraderQueryForm traderQueryForm){
		Customer customerDB = customerServiceImpl.getByMemberId(authMember.getId());
		traderQueryForm.setCustomerId(customerDB.getId());
		return customerServiceImpl.traderList(traderQueryForm);
	}


	@ApiOperation(value = "公开交易员列表", notes = "无需登录，支持类型过滤、排序；isTop=1 时仅返回顶级交易员")
	@GetMapping("/top-trader-list")
	public Page<TraderVo> topTraderList(
			@RequestParam(defaultValue = "1") Integer pageNum,
			@RequestParam(defaultValue = "10") Integer pageSize,
			@RequestParam(required = false) Integer traderType,
			@RequestParam(required = false) Integer orderBy,
			@RequestParam(required = false) Integer isTop) {
		TraderQueryForm form = new TraderQueryForm();
		form.setTraderType(traderType);
		form.setOrderBy(orderBy);
		form.setIsTop(isTop);
		return customerServiceImpl.topTraderList(pageNum, pageSize, form);
	}

	@ApiOperation(value = "交易员详情", notes = "交易员详情")
	@PutMapping("/trader-info/{traderId}")
	public TraderVo traderInfo(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember, @PathVariable Long traderId){
		Customer customerDB = customerServiceImpl.getByMemberId(authMember.getId());
		return customerServiceImpl.traderInfo(customerDB.getId(), traderId);
	}
	
	@ApiOperation(value = "取消交易员", notes = "取消交易员")
	@GetMapping("/cancel-trader")
	public Boolean cancelTrader(@SessionAttribute(DogeApi.SESSION_MEMBER) AuthMember authMember){
		return customerServiceImpl.cancelTrade(authMember);
	}
	
	private void synchronousInformation(String memberId,String nickname,String avatar) {
		CustomerMessage customerMessage = new CustomerMessage();
		customerMessage.setMemberId(memberId);
		customerMessage.setNickname(nickname);
		customerMessage.setAvatar(avatar);
		
		kafkaTemplate.send(KafkaTopic.SYNCHRONOUS_INFORMATION, JSON.toJSONString(customerMessage));
		
	}

}
