package com.goafanti.order.service.impl;


import com.goafanti.admin.service.DepartmentService;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.*;
import com.goafanti.common.enums.NoticeStatus;
import com.goafanti.common.model.*;
import com.goafanti.common.utils.DateUtils;
import com.goafanti.core.mybatis.BaseMybatisDao;
import com.goafanti.core.mybatis.page.Pagination;
import com.goafanti.core.shiro.token.TokenManager;
import com.goafanti.order.bo.*;
import com.goafanti.order.service.OrderInvoiceService;
import com.goafanti.order.service.OrderNewService;
import com.goafanti.organization.bo.OrganizationListOut;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;


@Service
public class OrderInvoiceServiceImpl extends BaseMybatisDao<TOrderInvoiceMapper> implements OrderInvoiceService {
	@Autowired
	private TOrderInvoiceMapper tOrderInvoiceMapper;
	@Autowired
	private TOrderNewMapper		tOrderNewMapper;
	@Autowired
	private DepartmentMapper	departmentMapper;
	@Autowired
	private AdminMapper	adminMapper;
	@Autowired
	private OrderNewService	orderNewService;
	@Autowired
	private TOrderMidMapper	tOrderMidMapper;
	@Autowired
	private InvoiceLogMapper invoiceLogMapper;
	@Autowired
	private DepartmentService departmentService;
	@Autowired
	private FinanceCountMapper financeCountMapper;

	@Override
	public int createServiceOrder(TOrderInvoice o) {
		o.setCreateTime(new Date());
		sendNoticeAndEmail(o);
		//前端直接会直接调取上一个发起数据给新开票，防止前一个数据为审核后
		if (o.getApproval()==2)o.setApproval(1);
		if (o.getStatus()!=1)o.setStatus(1);
		pushOrderInvoiceExamine(o);
		 Integer i=tOrderInvoiceMapper.insertSelective(o);
		addInvoiceLog(o.getId(),0);
		//非特批直接发到财务
		if (o.getApproval()==0&&o.getType()==0){
			String startTime = DateUtils.formatDate(o.getCreateTime(),AFTConstants.YYYYMMDD);
			Admin admin = adminMapper.selectOrderByFinanace(o.getOrderNo());
			FinanceCount financeCount = financeCountMapper.selectByAidAndDates(admin.getId(), startTime);
			addFinanceCount(startTime, admin, financeCount);
		}
		return i;
	}

	private void pushOrderInvoiceExamine(TOrderInvoice o) {
		//新增与修改
		List<Admin> admins =new ArrayList<>();
		StringBuffer str=new StringBuffer();
		TOrderNewBo t = tOrderNewMapper.getSaleIdByOno(o.getOrderNo());
		if (o.getType()==0){
			if (o.getApproval()==0){
				addExamineFinance(o, t);
			}else if(o.getApproval()==1&&o.getStatus()==1){
				admins = adminMapper.getAdminRoleTypeList(AFTConstants.HN_APPROVED);
			}else if (o.getApproval()==2){
				addExamineFinance(o, t);
			}else if (o.getApproval()==1&&o.getStatus()==3){
				o.setExamineName("");
			}
		}else if (o.getType()==1){
			if(o.getApproval()==0) {
				admins = adminMapper.listAdminBydepIdAndRoleType(t.getOrderDep(), AFTConstants.SALESMAN_ADMIN);
			}else if(o.getApproval()==1&&o.getStatus()==1) {
				admins = adminMapper.listAdminBydepIdAndRoleType(t.getOrderDep(), AFTConstants.COMPANY_MANAGER);
			}else if (o.getApproval()==2){
				admins = adminMapper.listAdminBydepIdAndRoleType(t.getOrderDep(), AFTConstants.SALESMAN_ADMIN);
			}else if (o.getApproval()==1&&o.getStatus()==3){
				o.setExamineName("");
			}
		}
		if (!admins.isEmpty()){
			for (Admin a : admins) {
				if (!str.toString().contains(a.getName()))str=str.append(a.getName()).append(",");
			}
			if (str.length()>0)o.setExamineName(str.substring(0,str.length()-1));
		}
	}

	private void addExamineFinance(TOrderInvoice o, TOrderNewBo t) {
		OrganizationListOut dep = departmentMapper.selectAllById(t.getOrderDep());
		o.setExamineName(dep.getFinanceName());
	}

	/**
	 *
	 * @param id 开票编号
	 * @param status  0发起 1开票通过 2开票拒绝 3特批通过 4特批拒绝 5修改提交
	 */
	void addInvoiceLog(Integer id, Integer status){
		InvoiceLog log = new InvoiceLog(id,status,TokenManager.getAdminId());
		invoiceLogMapper.insertSelective(log);
	}

	@Override
	public int updateServiceOrder(TOrderInvoice o) {
		sendNoticeAndEmail(o);
		addInvoiceLog(o.getId(),5);
		o.setStatus(1);
		if (o.getApproval()==2)o.setApproval(1);
		pushOrderInvoiceExamine(o);
		int i=tOrderInvoiceMapper.updateByPrimaryKeySelective(o);
		if (o.getApproval()==0){
			TOrderInvoice use = tOrderInvoiceMapper.selectByPrimaryKey(o.getId());
			String startTime = DateUtils.formatDate(use.getCreateTime(),AFTConstants.YYYYMMDD);
			Admin admin = adminMapper.selectOrderByFinanace(o.getOrderNo());
			FinanceCount financeCount = financeCountMapper.selectByAidAndDates(admin.getId(), startTime);
			addFinanceCount(startTime, admin, financeCount);
		}
		return i;
	}
	/**
	 * 	开票提交发送站内消息及邮件
	 * @param o
	 */
	private void sendNoticeAndEmail(TOrderInvoice o) {
		List<String> aids = new ArrayList<>();
		if (o.getStatus()==1) {//发起
			TOrderNew t=tOrderNewMapper.queryById(o.getOrderNo());
			if (o.getType()==0) {//省内
				if(o.getApproval()==0) {
					aids.add(departmentMapper.selectByPrimaryKey(t.getOrderDep()).getFinanceId());
				}else {
					for (Admin admin : adminMapper.getAdminRoleNameList("湖南特批开票")) {
						aids.add(admin.getId());
					}
				}
			}else if (o.getType()==1) {//省外
				if(o.getApproval()==0) {
					aids.addAll(adminMapper.listNameByDepAndName(t.getOrderDep(), AFTConstants.SALESMAN_ADMIN));
				}else {
					aids.addAll(adminMapper.listNameByDepAndName(t.getOrderDep(), AFTConstants.COMPANY_MANAGER));
				}
			}
		}
		TOrderNewBo order = tOrderNewMapper.getSaleIdByOno(o.getOrderNo());
		pushGeneralSendNoticeAndEmail(aids, NoticeStatus.ORDER_INVPICE_START.getCode(),order, TokenManager.getAdminId(),0);
	}
	public void pushGeneralSendNoticeAndEmail(List<String> alist, Integer type,TOrderNewBo o,String adminId,Integer approval){
		orderNewService.pushGeneralSendNoticeAndEmail(alist, type,o, adminId,approval);
	}

	@SuppressWarnings("deprecation")
	@Override
	public boolean checkAmount(TOrderInvoice t) {
		TOrderNew tn=tOrderNewMapper.queryById(t.getOrderNo());
		String i=tOrderInvoiceMapper.checkApplyAmount(t.getOrderNo(),t.getId());//新建时直接查所有数据,修改时除掉修改订单
			//处理精度问题
		BigDecimal q=t.getAmount().add(new BigDecimal(i)).setScale(4, BigDecimal.ROUND_DOWN);;
		BigDecimal w=tn.getTotalAmount();
		int	flag=q.compareTo(w);
		if (flag>0) {
			return true;
		}
		return false;
	}


	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TOrderInvoiceBo> financeOrderInvoiceList(InputOrderInvoiceBo o,Integer pageNo,
			Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(pageSize==null||pageSize<0)pageSize=10;
		if(pageNo==null||pageNo<0)pageNo=1;
		List<String> aDep=new ArrayList<>();
		//财务专员查看自己的
		if (TokenManager.hasRole(AFTConstants.FINANCE)) {
			aDep.addAll(adminMapper.getFinanceDep(TokenManager.getAdminId()));
		}
		//财务经理
		if (TokenManager.hasRole(AFTConstants.FINANCE_MANAGER)) {
			aDep.addAll(adminMapper.selectDepIdWithSpuerId(TokenManager.getAdminId()));
		}
		//营销管理员
		if (TokenManager.hasRole(AFTConstants.SALESMAN_ADMIN)) {
			aDep.addAll(departmentService.selectMyDeps());

		}
		if (TokenManager.hasRole(AFTConstants.FINANCE_ADMIN)) {
			if (o.getDeps()!=null){
				aDep.addAll(departmentService.parseArray(o.getDeps()));
			}
		}
		if(o.getDeps()==null){
			if (!aDep.isEmpty()){
				params.put("deps", aDep);
			}
		}else {
			aDep=departmentService.comparePermissions(aDep,o.getDeps());
			if (aDep.isEmpty()){
				return new Pagination<>(1,10,0);
			}
			params.put("deps", aDep);

		}
		if(o.getType()!=null)params.put("type", o.getType());

		if (null !=o.getAll()){
			params.put("all",o.getAll());
		}else {
			params.put("all",0);
		}
		if(StringUtils.isNotBlank(o.getOrderNo()))params.put("orderNo", o.getOrderNo());
		if(StringUtils.isNotBlank(o.getName()))params.put("name", o.getName());
		if(null!=o.getApproval())params.put("approval", o.getApproval());
		if(null!=o.getStatus())params.put("status", o.getStatus());
		if(null!=o.getContractNo())params.put("contractNo", o.getContractNo());
		//这里不是客户得名称，而是开票的单位名称
		if(null!=o.getUserName())params.put("userName", o.getUserName());
		if(null!=o.getInvoiceType())params.put("invoiceType", o.getInvoiceType());
		if(null!=o.getStartTime())params.put("startTime", o.getStartTime());
		if(null!=o.getEndTime())params.put("endTime", o.getEndTime()+" 23:59:59");
		return (Pagination<TOrderInvoiceBo>)findPage("financeOrderInvoiceList", "financeOrderInvoiceCount", params, pageNo, pageSize);

	}

	@Override
	public TOrderInvoiceDetails selectByIdOrderInvoice(Integer id) {
		return tOrderInvoiceMapper.selectByInvoiceDitails(id);
	}

	@Override
	public TOrderInvoiceDetails getInvoiceDetails(String orderNo) {
		return tOrderInvoiceMapper.getInvoiceDetails(orderNo);
	}




	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TOrderInvoiceBo> salesmanOrderInvoiceList( String orderNo,
			Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(pageSize==null||pageSize<0)pageSize=10;
		if(pageNo==null||pageNo<0)pageNo=1;
		if(StringUtils.isNotBlank(orderNo))params.put("orderNo", orderNo);
		return (Pagination<TOrderInvoiceBo>)findPage("salesmanOrderInvoiceList", "salesmanOrderInvoiceCount", params, pageNo, pageSize);
	}

	@Override
	public int updatefinanceExamine(Integer id, Integer examine, String reason) {
		TOrderInvoice t=new TOrderInvoice();
		t.setId(id);
		t.setRejectReason(reason);
		t.setStatus(examine);
		t.setExamineName("");
		//examine 2通过 3拒绝
		List<String> aids = new ArrayList<>();
		TOrderInvoice t2=tOrderInvoiceMapper.selectByPrimaryKey(id);
		TOrderNew o=tOrderNewMapper.queryById(t2.getOrderNo());
		Integer type=null;
		if(examine==3){
			type=NoticeStatus.ORDER_INVPICE_NO.getCode();
			aids.add(o.getSalesmanId());
			addInvoiceLog(id,2);
		}else if(examine==2) {
			type=NoticeStatus.ORDER_INVPICE_END.getCode();
			aids.add(o.getSalesmanId());
			//重新计算开票金额
			addInvoiceLog(id,1);
		}
		pushInvoiceFinancialCount(t2,examine);
		TOrderNewBo order = tOrderNewMapper.getSaleIdByOno(t2.getOrderNo());
		pushGeneralSendNoticeAndEmail(aids, type,order, TokenManager.getAdminId(),0);
		tOrderInvoiceMapper.updateByPrimaryKeySelective(t);
		if(examine==2)tOrderMidMapper.updateInvoice(t2.getOrderNo());
		return 1;
	}

	/**
	 *
	 * @param t2 开票信息
	 * @param examine  2通过 3拒绝
	 */
	private void pushInvoiceFinancialCount(TOrderInvoice t2, Integer examine) {
		String startTime = DateUtils.formatDate(t2.getCreateTime(),AFTConstants.YYYYMMDD);
		Admin admin = adminMapper.selectOrderByFinanace(t2.getOrderNo());
		FinanceCount financeCount = financeCountMapper.selectByAidAndDates(admin.getId(), startTime);
		if (examine==2){
			//特批通过和特批是财务审核
			if (financeCount!=null&&(t2.getApproval()==2||t2.getApproval()==0)){
				FinanceCount newFinanceCount=new FinanceCount();
				newFinanceCount.setId(financeCount.getId());
				newFinanceCount.setInvoiceUnauditedCount(financeCount.getInvoiceUnauditedCount()-1);
				financeCountMapper.updateByPrimaryKeySelective(newFinanceCount);
				//特批审核是审核完到财务
			}else if (t2.getApproval()==1){
				addFinanceCount(startTime, admin, financeCount);
			}

		}else if (examine==3){
			if (financeCount!=null&&(t2.getApproval()==2||t2.getApproval()==0)){
				FinanceCount newFinanceCount=new FinanceCount();
				newFinanceCount.setId(financeCount.getId());
				newFinanceCount.setInvoiceCount(financeCount.getInvoiceCount()-1);
				newFinanceCount.setInvoiceUnauditedCount(financeCount.getInvoiceUnauditedCount()-1);
				financeCountMapper.updateByPrimaryKeySelective(newFinanceCount);
			}
		}
	}

	private void addFinanceCount(String startTime, Admin admin, FinanceCount financeCount) {
		if (financeCount ==null){
			financeCount =FinanceCount.initialization(admin.getId(), startTime);
			financeCount.setInvoiceCount(1);
			financeCount.setInvoiceUnauditedCount(1);
			financeCountMapper.insertSelective(financeCount);
		}else {
			FinanceCount newFinanceCount=new FinanceCount();
			newFinanceCount.setId(financeCount.getId());
			newFinanceCount.setInvoiceCount(financeCount.getInvoiceCount()+1);
			newFinanceCount.setInvoiceUnauditedCount(financeCount.getInvoiceUnauditedCount()+1);
			financeCountMapper.updateByPrimaryKeySelective(newFinanceCount);
		}
	}


	@SuppressWarnings("unchecked")
	@Override
	public Pagination<TOrderInvoiceBo> approvalOrderInvoiceList(Integer status,Integer approval,Integer type, String orderDep, String orderNo, String name,String userName,
			Integer pageNo, Integer pageSize) {
		Map<String, Object> params = new HashMap<String, Object>();
		if(pageSize==null||pageSize<0)pageSize=10;
		if(pageNo==null||pageNo<0)pageNo=1;
		if(StringUtils.isNotBlank(orderDep))params.put("orderDep", orderDep);
		if(StringUtils.isNotBlank(orderNo))params.put("orderNo", orderNo);
		if(StringUtils.isNotBlank(name))params.put("name", name);
		if(StringUtils.isNotBlank(userName))params.put("userName", userName);
		if(approval!=null)params.put("approval", approval);
		if(status!=null)params.put("status", status);
		//0省内 1省外 2查看所有省外
		if(type==0||type==1)params.put("type", type);
		if (type==2) {
			params.put("type", 1);
			params.put("special", 1);
		}
		if (type ==1&&!TokenManager.hasRole(AFTConstants.SUPERADMIN)) {
			//如果是省外则直接查本部门
			Admin a=adminMapper.selectById(TokenManager.getAdminId());
			params.put("aDep", a.getDepartmentId());
		}
		return (Pagination<TOrderInvoiceBo>)findPage("approvalOrderInvoiceList", "approvalOrderInvoiceCount", params, pageNo, pageSize);
	}

	@Override
	public int updateapprovalExamine(Integer id, Integer examine, String reason) {
 		TOrderInvoice t=new TOrderInvoice();
		t.setId(id);
		t.setRejectReason(reason);
		List<String> aids=new ArrayList<>();
		TOrderInvoice o=tOrderInvoiceMapper.selectByPrimaryKey(id);
		t.setApproval(o.getApproval());
		t.setType(o.getType());
		t.setStatus(o.getStatus());
		t.setOrderNo(o.getOrderNo());
		TOrderNew ts=tOrderNewMapper.queryById(o.getOrderNo());
		//examine 2通过 3拒绝
		Integer type =null;
		if(examine==3) {
		t.setStatus(examine);
		type= NoticeStatus.ORDER_INVPICE_APPROVA_NO.getCode();
		aids.add(ts.getSalesmanId());
			addInvoiceLog(id,4);
		}else {
			t.setApproval(examine);
			addInvoiceLog(id,3);
			type= NoticeStatus.ORDER_INVPICE_APPROVA_YES.getCode();
			if (o.getType()==0) {
				aids.add(departmentMapper.selectByPrimaryKey(ts.getOrderDep()).getFinanceId());
			}else if(o.getType()==1) {
				aids.addAll(adminMapper.listNameByDepAndName(ts.getOrderDep(), AFTConstants.SALESMAN_ADMIN));
			}
			String startTime = DateUtils.formatDate(o.getCreateTime(),AFTConstants.YYYYMMDD);
			Admin admin = adminMapper.selectOrderByFinanace(o.getOrderNo());
			FinanceCount financeCount = financeCountMapper.selectByAidAndDates(admin.getId(), startTime);
			addFinanceCount(startTime,admin,financeCount);
		}

		pushOrderInvoiceExamine(t);
		TOrderNewBo order = tOrderNewMapper.getSaleIdByOno(o.getOrderNo());
		pushGeneralSendNoticeAndEmail(aids,type,order, TokenManager.getAdminId(),0);
		return tOrderInvoiceMapper.updateByPrimaryKeySelective(t);
	}
	@Override
	public List<OutInvoiceLog> InvoiceLog(Integer id) {
		List<OutInvoiceLog>  list=tOrderInvoiceMapper.selectInvoiceLog(id);
		return list;
	}

	@Override
	public boolean checkDelete(Integer id) {
		TOrderInvoice t=tOrderInvoiceMapper.selectByPrimaryKey(id);
        return t.getStatus() == 1 || t.getStatus() == 2;
    }

	@Override
	public Object delete(Integer id) {
		TOrderInvoice t=new TOrderInvoice();
		t.setId(id);
		t.setStatus(4);

		return tOrderInvoiceMapper.updateByPrimaryKeySelective(t);
	}
}
