/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.finance.service.impl;

import cn.hutool.core.collection.CollUtil;
import org.springblade.common.enums.*;
import org.springblade.common.utils.CommonUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.modules.api.request.CustomWineOrderSave;
import org.springblade.modules.api.request.SaveDIYInfoRequest;
import org.springblade.modules.api.request.SubmitOrderRequest;
import org.springblade.modules.api.service.IMallService;
import org.springblade.modules.api.service.SubmitOrderService;
import org.springblade.modules.custom.entity.*;
import org.springblade.modules.custom.service.*;
import org.springblade.modules.finance.entity.CustomWineDiy;
import org.springblade.modules.finance.entity.CustomWineOrder;
import org.springblade.modules.finance.entity.Order;
import org.springblade.modules.finance.entity.OrderDetail;
import org.springblade.modules.finance.service.ICustomWineDiyService;
import org.springblade.modules.finance.service.IOrderDetailService;
import org.springblade.modules.finance.service.IOrderService;
import org.springblade.modules.finance.vo.CustomWineOrderVO;
import org.springblade.modules.finance.mapper.CustomWineOrderMapper;
import org.springblade.modules.finance.service.ICustomWineOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.modules.finance.wrapper.CustomWineOrderWrapper;
import org.springblade.modules.platform.entity.UserAddress;
import org.springblade.modules.platform.service.IUserAddressService;
import org.springblade.modules.resource.builder.oss.OssBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 定制酒订单 服务实现类
 *
 * @author BladeX
 * @since 2023-02-14
 */
@Service("customWineOrderServiceImpl")
public class CustomWineOrderServiceImpl extends ServiceImpl<CustomWineOrderMapper, CustomWineOrder> implements ICustomWineOrderService, SubmitOrderService {

	@Autowired
	private IBottleBodyService bottleBodyService;
	@Autowired
	private IBottleCapService bottleCapService;
	@Autowired
	private IBottleLabelService bottleLabelService;
	@Autowired
	private IWineBoxService wineBoxService;
	@Autowired
	private IWineCaseService wineCaseService;
	@Autowired
	private IBaseWineService baseWineService;
	@Autowired
	private IHandbagService handbagService;
	@Autowired
	private IUserAddressService userAddressService;
	@Autowired
	private IBartenderSkillService bartenderSkillService;
	@Autowired
	private IOrderService orderService;
	@Autowired
	private IOrderDetailService orderDetailService;
	@Autowired
	private IMallService mallService;
	@Autowired
	private ICustomWineDiyService customWineDiyService;
	@Autowired
	private OssBuilder ossBuilder;
	@Autowired
	private ISpecialFormulaService specialFormulaService;


	@Override
	public IPage<CustomWineOrderVO> selectCustomWineOrderPage(IPage<CustomWineOrderVO> page, CustomWineOrderVO customWineOrder) {
		return page.setRecords(baseMapper.selectCustomWineOrderPage(page, customWineOrder));
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public String saveOrder(CustomWineOrderSave param, Long userId) throws Exception {
		UserAddress userAddress = userAddressService.getById(param.getUserAddressId());
		Assert.notNull(userAddress, "用户地址信息不存在");

		// 构建order实体
		Order order = orderService.init();
		order.setOrderType(OrderTypeEnum.CUSTOM_WINE.getValue());
		order.setQuantity(param.getQuantity());
		order.setDistributeMode(param.getDistributeMode());
		order.setConsignee(userAddress.getRealName());
		order.setConsigneePhoneNumber(userAddress.getPhone());

		// 定制酒订单实体
		CustomWineOrder customWineOrder = buildCustomWineOrder(param);
		// 构建订单明细实体
		OrderDetail orderDetail = buildOrderDetail(param, userAddress);
		// 计算一整套定制酒的价格，乘以订单数量，得到总价
		BigDecimal totalPrice = calculateTotalPrice(customWineOrder).multiply(new BigDecimal(order.getQuantity()));
		order.setTotalAmount(totalPrice);
		order.setPaymentAmount(totalPrice);
		// 计算优惠金额
		BigDecimal discountAmount = mallService.calDiscountAmount(order.getOrderNo(), totalPrice, param.getCouponUserId());
		order.setDiscountAmount(discountAmount);// 优惠金额
		order.setPostage(new BigDecimal(0));// 邮费
		// 取酒盒图片作为订单图片展示
		WineCase wineCase = wineCaseService.getById(customWineOrder.getWineCaseId());
		order.setImage(wineCase.getImage());
		orderService.save(order);

		customWineOrder.setOrderId(order.getId());
		this.save(customWineOrder);

		orderDetail.setOrderId(order.getId());
		orderDetailService.save(orderDetail);

		CustomWineDiy diy = new CustomWineDiy();
		diy.setOrderNo(order.getOrderNo());
		diy.setWineCaseImage(param.getWineCaseImage());
		diy.setWineBoxImage(param.getWineBoxImage());
		diy.setWineLabelImage(param.getWineLabelImage());
		diy.setHandbagImage(param.getHandbagImage());
		customWineDiyService.save(diy);

		return order.getOrderNo();
	}

	@Override
	public CustomWineOrderVO getByOrderId(Long orderId) {
		CustomWineOrder customWineOrder = this.lambdaQuery().eq(CustomWineOrder::getOrderId, orderId).one();
		CustomWineOrderVO vo = CustomWineOrderWrapper.build().entityVO(customWineOrder);
		BaseWine baseWine = baseWineService.getById(vo.getBaseWineId());
		vo.setBaseWineImage(baseWine.getImage());
		if (vo.getBottleLabelId() != null) {
			BottleLabel bottleLabel = bottleLabelService.getById(vo.getBottleLabelId());
			vo.setLabelImage(bottleLabel.getImage());
		}
		if (vo.getBottleBodyId() != null) {
			BottleBody bottleBody = bottleBodyService.getById(vo.getBottleBodyId());
			vo.setBottleBodyImage(bottleBody.getImage());
		}
		if (vo.getBottleCapId() != null) {
			BottleCap bottleCap = bottleCapService.getById(vo.getBottleCapId());
			vo.setBottleCapImage(bottleCap.getImage());
		}
		if (vo.getWineBoxId() != null) {
			WineBox wineBox = wineBoxService.getById(vo.getWineBoxId());
			vo.setWineBoxImage(wineBox.getImage());
		}
		if (vo.getWineCaseId() != null) {
			WineCase wineCase = wineCaseService.getById(vo.getWineCaseId());
			vo.setWineCaseImage(wineCase.getImage());
		}
		if (vo.getHandbagId() != null) {
			Handbag handbag = handbagService.getById(vo.getHandbagId());
			vo.setHandbagImage(handbag.getImage());
		}
		return vo;
	}

	@Override
	public void saveDIYInfo(SaveDIYInfoRequest request) {
		try {
			CustomWineDiy diy = BeanUtil.copy(request, CustomWineDiy.class);
			Assert.notNull(diy, "diy不能为空");
			diy.setWineCaseImage(this.upload(request.getWineCaseImageFile()));
			diy.setWineBoxImage(this.upload(request.getWineBoxImageFile()));
			diy.setWineLabelImage(this.upload(request.getWineLabelImageFile()));
			diy.setQrCode(this.upload(request.getQrCodeFile()));
			diy.setHandbagImage(this.upload(request.getHandbagImageFile()));
			customWineDiyService.save(diy);
		} catch (Exception e) {
			throw new ServiceException("保存DIY信息失败");
		}
	}

	private String upload(MultipartFile file) throws IOException {
		BladeFile bladeFile = ossBuilder.template().putFile(file.getOriginalFilename(), file.getInputStream());
		return bladeFile.getLink();
	}

	/**
	 * 计算定制酒订单价格
	 */
	private BigDecimal calculateTotalPrice(CustomWineOrder order) {
		order.setBottleBodyQuantity(6);
		order.setBottleCapQuantity(6);
		BigDecimal bottleBodyPrice = order.getBottleBodyPrice().multiply(new BigDecimal(6));
		BigDecimal bottleCapPrice = order.getBottleCapPrice().multiply(new BigDecimal(6));
		BigDecimal bottleLabelPrice = BigDecimal.valueOf(0);
		if (order.getBottleLabelPrice() != null) {
			order.setBottleLabelQuantity(6);
			 bottleLabelPrice = order.getBottleLabelPrice().multiply(new BigDecimal(6));
		}
		BigDecimal wineBoxPrice = BigDecimal.valueOf(0);
		if (order.getWineBoxPrice() != null) {
			order.setWineBoxQuantity(6);
			 wineBoxPrice = order.getWineBoxPrice().multiply(new BigDecimal(6));
		}
		order.setWineCaseQuantity(1);
		order.setBaseWineQuantity(1);
		BigDecimal wineCasePrice = order.getWineCasePrice().multiply(new BigDecimal(1));
		BigDecimal baseWinePrice = order.getBaseWinePrice().multiply(new BigDecimal(1));
		BigDecimal handbagPrice = BigDecimal.valueOf(0);
		if (order.getHandbagPrice() != null) {
			order.setHandbagQuantity(6);
			handbagPrice = order.getHandbagPrice().multiply(new BigDecimal(6));
		}
		BigDecimal total = bottleBodyPrice.add(handbagPrice).add(bottleCapPrice).add(bottleLabelPrice).add(wineBoxPrice).add(wineCasePrice).add(baseWinePrice);
		if (order.getSpecialFormulaId() != null) {
			SpecialFormula specialFormula = specialFormulaService.getById(order.getSpecialFormulaId());
			Assert.notNull(specialFormula, "特调配方不存在");
			total = total.add(specialFormula.getPrice());
		}
		// 将酒瓶、酒盖等价格相加
		return total;
	}

	/**
	 * 构建订单明细实体
	 */
	private OrderDetail buildOrderDetail(CustomWineOrderSave param, UserAddress userAddress) {
		OrderDetail orderDetail = new OrderDetail();
		orderDetail.setProvince(userAddress.getProvince());
		orderDetail.setCity(userAddress.getCity());
		orderDetail.setDistrict(userAddress.getDistrict());
		orderDetail.setStreet(userAddress.getStreet());
		orderDetail.setAddress(userAddress.getDetail());
		orderDetail.setRemark(param.getRemark());
		return orderDetail;
	}

	/**
	 * 构建 CustomWineOrder 实体
	 */
	private CustomWineOrder buildCustomWineOrder(CustomWineOrderSave param) throws Exception {
		CustomWineOrder order = new CustomWineOrder();
		order.setSpecialBaseWineId(param.getSpecialBaseWineId());
		order.setSpecialFormulaId(param.getSpecialFormulaId());
		order.setTrademarkId(param.getTrademarkId());
		BottleBody bottleBody = bottleBodyService.getById(param.getBottleBodyId());
		Assert.notNull(bottleBody, "瓶身数据不存在");
		BottleCap bottleCap = bottleCapService.getById(param.getBottleCapId());
		Assert.notNull(bottleCap, "瓶盖信息不存在");
		BottleLabel bottleLabel = bottleLabelService.getById(param.getBottleLabelId());
//		Assert.notNull(bottleLabel, "标贴信息不存在");
		WineBox wineBox = wineBoxService.getById(param.getWineBoxId());
//		Assert.notNull(wineBox, "酒盒信息不存在");
		WineCase wineCase = wineCaseService.getById(param.getWineCaseId());
		Assert.notNull(wineCase, "酒箱信息不存在");
		Handbag handbag = handbagService.getById(param.getHandbagId());
//		Assert.notNull(handbag, "手提包信息不存在");
		// 瓶身信息
		this.setAttr(order, bottleBody, "bottleBody");
		// 瓶盖信息
		this.setAttr(order, bottleCap, "bottleCap");
		// 标贴信息
		if (bottleLabel != null) {
			this.setAttr(order, bottleLabel, "bottleLabel");
		}
		// 酒盒信息
		if (wineBox !=null ){
			this.setAttr(order, wineBox, "wineBox");
		}
		// 酒箱信息
		this.setAttr(order, wineCase, "wineCase");
		// 手提包信息
		if (handbag != null) {
			this.setAttr(order, handbag, "handbag");
		}
		// 基酒信息
		order.setBaseWineType(param.getBaseWineType());
		if (BaseWineTypeEnum.FINISHED.getValue().equals(order.getBaseWineType())) {
			BaseWine baseWine = baseWineService.getById(param.getBaseWineId());
			this.setAttr(order, baseWine, "baseWine");
		} else {
			BartenderSkill bartenderSkill = bartenderSkillService.getById(param.getBartenderSkillId());
			order.setBartenderId(param.getBartenderId());
			order.setBartenderSkillId(param.getBartenderSkillId());
			order.setBartenderSkillTitle(bartenderSkill.getTitle());
			order.setBaseWinePrice(bartenderSkill.getPrice());
			order.setBaseWineQuantity(6);
		}
		order.setFont(param.getFont());
		order.setTemplate(param.getTemplate());
		order.setCustomContent(param.getCustomContent());
		return order;
	}

	/**
	 * 通过反射设置属性
	 * @param target 目标类
	 * @param source 源类
	 * @param fieldName 属性名
	 * @throws Exception
	 */
	private void setAttr(CustomWineOrder target, Object source, String fieldName) throws Exception {
		Class<? extends CustomWineOrder> targetClass = target.getClass();
		Class<?> sourceClass = source.getClass();
		ArrayList<String> fieldList = CollUtil.newArrayList("Id", "Name", "Price", "Unit");
		for (String field : fieldList) {
			Method method = sourceClass.getMethod("get" + field);
			Object value = method.invoke(source);
			Field declaredField;
//			if ("DefaultNum".equals(field)) {
//				declaredField = targetClass.getDeclaredField(fieldName + "Quantity");
//			} else {
				declaredField = targetClass.getDeclaredField(fieldName + field);
//			}
			declaredField.setAccessible(true);// 抑制Java对修饰符的检查
			declaredField.set(target, value);
		}
	}

	@Override
	public String submitOrder(SubmitOrderRequest request) {
		return null;
	}
}
