/*
 *      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.desk.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.springblade.bank.cardswallow.entity.CardSwallow;
import org.springblade.bank.goodsuse.entity.GoodsUse;
import org.springblade.bank.keypwd.entity.KeyPwd;
import org.springblade.bank.message.entity.Message;
import org.springblade.bank.postchange.entity.PostChange;
import org.springblade.bank.returns.entity.Returns;
import org.springblade.bank.sealhandover.entity.SealHandover;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.desk.entity.Notice;
import org.springblade.modules.desk.mapper.NoticeMapper;
import org.springblade.modules.desk.service.INoticeService;
import org.springblade.modules.desk.vo.NoticeVO;
import org.springblade.modules.publishevent.event.HangxinNoticeEvent;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.Role;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.*;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author Chill
 */
@Service
@AllArgsConstructor
public class NoticeServiceImpl extends BaseServiceImpl<NoticeMapper, Notice> implements INoticeService {

	private final IUserService userService;
	private final IDictService dictService;
	private final IDeptService deptService;
	private final IRoleService roleService;
	private final IParamService paramService;
	private final ApplicationEventPublisher eventPublisher;

	@Override
	public IPage<NoticeVO> selectNoticePage(IPage<NoticeVO> page, NoticeVO notice) {
		// 若不使用mybatis-plus自带的分页方法，则不会自动带入tenantId，所以我们需要自行注入
		notice.setTenantId(AuthUtil.getTenantId());
		return page.setRecords(baseMapper.selectNoticePage(page, notice));
	}

	@Override
	public IPage<NoticeVO> selectMyNoticePage(IPage<NoticeVO> page, NoticeVO notice) {
		notice.setTenantId(AuthUtil.getTenantId());
		return page.setRecords(baseMapper.selectMyNoticePage(page, notice));
	}

	@Override
	public List<Notice> selectMyNoticeAll() {
		NoticeVO notice = new NoticeVO();
		notice.setTenantId(AuthUtil.getTenantId());
		notice.setCurrentUserId(AuthUtil.getUserId());
		notice.setHadRead(0);
		return baseMapper.selectMyNoticePage(notice);
	}

	@Override
	public boolean sendNotice(NoticeVO notice) {
		notice.setType("0"); //系統
		if (StringUtil.isBlank(notice.getTargetIds())){
			List<String> deptIds = Func.toStrList(notice.getDeptId());
			List<String> roleIds = Func.toStrList(notice.getRoleId());
			List<User> userList = userService.getUsersByDeptIdsRoleIds(deptIds, roleIds);
			List<Long> userIdList = userList.stream().map(user -> user.getId()).collect(Collectors.toList());
			String join = StringUtil.join(userIdList);
			notice.setTargetIds(join);
		}
		if (notice.getTargetEhrs() == null && StringUtil.isNotBlank(notice.getTargetIds())){
			String[] split = notice.getTargetIds().split(",");
			List<String> userEhrList = new ArrayList<>();
			for (int i = 0; i < split.length; i++) {
				String userIdStr = split[i];
				User user = userService.getById(userIdStr);
				userEhrList.add(user.getEhr());
			}
			notice.setTargetEhrs(StringUtil.join(userEhrList, "|"));
		}

		if (notice.getSendHangxin() == null || notice.getSendHangxin().equals(true)){
			HangxinNoticeEvent hangxinNoticeEvent = new HangxinNoticeEvent(notice);
			eventPublisher.publishEvent(hangxinNoticeEvent);
		}

		return save(notice);
	}

	@Override
	public boolean sendKeyPwdNotice(KeyPwd keyPwd, boolean isEdit, boolean isComplete) {
		//有關XXX(分類+種類+鎖匙/密碼)的交接登記已於X年X月X日完成；交出人﹕XXX；接收人﹕XXX
		// ORM-通知
		//【網點鎖匙/密碼/實物交接登記表】
		//分行用戶提交了有關(分類種類)的交接登記，請登入系統進行確認。
		String categoryName = getCategoryName(keyPwd);
		String now = DateUtil.formatDate(DateUtil.now());
		String title = "ORM-通知【網點鎖匙/密碼/實物交接登記表】";
		if (isEdit){
			title += "更正：";
		}
		Dept dept;
		if (keyPwd.getCreateUser() == null){
			dept = deptService.getById(AuthUtil.getDeptId());
		}else {
			User createUser = userService.getById(keyPwd.getCreateUser());
			dept = deptService.getById(createUser.getDeptId());
		}
		String HandoverName = (dept.getDeptCategory().equals(1)) ? "分行用戶" : keyPwd.getHandoverPersonName();
		String ReceiverName = (StringUtil.isBlank(keyPwd.getReceiverName()) && dept.getDeptCategory().equals(1)) ? "分行用戶" : keyPwd.getReceiverName();

		if (!isComplete){
			title += HandoverName + "提交了" + "有關 （" + categoryName + "） 的交接登記" + "，請登入系統進行確認。";
		}else{
			if (keyPwd.getIsTurnIn().equals(0)){
				//非上繳
				title += "有關（" + categoryName + "）的交接登記，已於" + now + "完成；交出人：" + HandoverName + "；接收人：" + ReceiverName + "。";
			}
			if (keyPwd.getIsTurnIn().equals(1)) {
				// 上繳
				title += "有關（" + categoryName + "）的交接登記，已於" + now + "完成上繳。";
			}
		}

		User user1 = userService.getUserByEhr(keyPwd.getHandoverPersonNo());
		User user2 = userService.getUserByEhr(keyPwd.getReceiverNo());

		List<Long> targetList = new ArrayList<>();
		List<String> userEhrtList = new ArrayList<>();
		if (user1 != null){
			targetList.add(user1.getId());
			userEhrtList.add(user1.getEhr());
		}
		if (user2 != null){
			targetList.add(user2.getId());
			userEhrtList.add(user2.getEhr());
		}

		NoticeVO notice = new NoticeVO();
		notice.setTitle(title);
		notice.setBusinessType("keypwd");
		notice.setTargetIds(StringUtil.join(targetList));
		notice.setTargetEhrs(StringUtil.join(userEhrtList, "|"));

		return sendNotice(notice);
	}

	@Override
	public boolean sendCardSwallowNotice(CardSwallow cardSwallow, boolean isEdit) {
		String title = "ORM-通知【自助設備吞卡資料】";
		if (isEdit){
			title += "更正：";
		}
		title += "營運部已發佈新消息，請查閱";
		Dept dept = deptService.getByOrgNo(cardSwallow.getSendOrgNo());

		NoticeVO notice = new NoticeVO();
		notice.setTitle(title);
		notice.setBusinessType("cardswallow");
		notice.setDeptId(dept.getId()+"");
		notice.setRoleId(null);
		return sendNotice(notice);
	}

	@Override
	public boolean sendReturnsNotice(Returns returns, boolean isEdit) {
		String title = "ORM-通知【新開戶退件登記表】";
		if (isEdit){
			title += "更正：";
		}
		title += "營運部已發佈新消息，請查閱";
		Dept dept = deptService.getByOrgNo(returns.getSubOrgNo());

		NoticeVO notice = new NoticeVO();
		notice.setTitle(title);
		notice.setBusinessType("returns");
		notice.setDeptId(dept.getId()+"");
		notice.setRoleId(null);
		return sendNotice(notice);
	}

	@Override
	public boolean sendMessageNotice(Message message, boolean isEdit) {
		String title = "ORM-通知【信息發佈】";
		if (isEdit){
			title += "更正：";
		}
		title += "營運部已發佈新消息，請查閱";
		NoticeVO notice = new NoticeVO();
		notice.setTitle(title);
		notice.setBusinessType("message");
		notice.setDeptId(message.getDeptId());
		notice.setRoleId(message.getRoleId());
		notice.setTargetIds(message.getTargetIds());
		notice.setContent("標題：" + message.getTitle() + ";內文：" + message.getContent());

		if (StringUtil.isNotBlank(message.getTargetIds())){
			String[] split = message.getTargetIds().split(",");
			List<String> userEhrList = new ArrayList<>();
			for (int i = 0; i < split.length; i++) {
				String userIdStr = split[i];
				User user = userService.getById(userIdStr);
				userEhrList.add(user.getEhr());
			}
			notice.setTargetEhrs(StringUtil.join(userEhrList, "|"));
		}

		return sendNotice(notice);
	}

	@Override
	public boolean sendSealNotice(SealHandover sealHandover, boolean isEdit, boolean isComplete) {
		//有關XXX(印章種類+印章編號)的交接登記已於X年X月X日完成；交出人﹕XXX；接收人﹕XXX
		String seal_type = dictService.getValue("seal_type", sealHandover.getSealType());
		String now = DateUtil.formatDate(DateUtil.now());
		User user1 = userService.getUserByEhr(sealHandover.getHandoverPersonNo());
		User user2 = userService.getUserByEhr(sealHandover.getReceiverNo());
		List<Long> userList = new ArrayList<>();
		List<String> userEhrList = new ArrayList<>();
		if (user1 != null){
			userList.add(user1.getId());
			userEhrList.add(user1.getEhr());
		}
		if (user2 != null){
			userList.add(user2.getId());
			userEhrList.add(user2.getEhr());
		}
		String title = "ORM-通知【業務印章交接登記表】";
		if (isEdit){
			title += "更正：";
		}
		Dept dept = deptService.getById(AuthUtil.getDeptId());
		String HandoverName = (StringUtil.isBlank(sealHandover.getHandoverPersonName()) && dept.getDeptCategory().equals(1)) ? "分行用戶" : sealHandover.getHandoverPersonName();
		String ReceiverName = (StringUtil.isBlank(sealHandover.getReceiverName()) && dept.getDeptCategory().equals(1)) ? "分行用戶" : sealHandover.getReceiverName();

		if (!isComplete){
//			if (sealHandover.getIsTurnIn().equals(0)){
				title += HandoverName + "提交了" + "有關 （" + seal_type + sealHandover.getSealNo() + "） 的交接登記" + "，請登入系統進行確認。";
//			}
		}else{
			if (sealHandover.getIsTurnIn().equals(0)){
				title += "有關 （" + seal_type + sealHandover.getSealNo() + "） 的交接登記已於" + now + "完成；交出人：" + HandoverName + "；接收人：" + ReceiverName + "。";
			}else{
				title += "有關 （" + seal_type + sealHandover.getSealNo() + "） 的交接登記已於" + now + "完成上繳；交出人：" + HandoverName + "；接收人：" + ReceiverName + "。";
			}
		}

		NoticeVO notice = new NoticeVO();
		notice.setTitle(title);
		notice.setBusinessType("sealhandover");
		notice.setTargetIds(StringUtil.join(userList));
		notice.setTargetEhrs(StringUtil.join(userEhrList, "|"));
		return sendNotice(notice);
	}

	@Override
	public boolean sendPostChangeNotice(PostChange postChange, boolean isEdit, boolean isComplete) {
		NoticeVO notice = new NoticeVO();


		Dept dept = deptService.getByOrgNo(postChange.getOrgNo());
		String title = "ORM-通知【網點出納主管及專管員崗位變更記錄表】";
		if (isEdit){
			title += "更正：";
		}
		if (isComplete){
			title += dept.getDeptName() + "機構已提交網點出納主管及專管員崗位變更記錄表，請登陸系統查詢";
			List<Role> roles = roleService.getRolesByAlias("cashierTeam");
			List<String> roleIds = roles.stream().map(role -> role.getId() + "").collect(Collectors.toList());
			List<User> users = userService.getUsersByDeptIdsRoleIds(null, roleIds);
			List<String> userIds = users.stream().map(user -> user.getId() + "").collect(Collectors.toList());
			List<String> userEhrs = users.stream().map(user -> user.getEhr()).collect(Collectors.toList());
			notice.setTargetIds(StringUtil.join(userIds));
			notice.setTargetEhrs(StringUtil.join(userEhrs, "|"));

			notice.setRoleId(StringUtil.join(roleIds));
		}else{
			User createUser = userService.getById(postChange.getCreateUser());
			title += createUser.getName() + "已提交網點出納主管及專管員崗位變更記錄表，請登陸系統查詢";
			notice.setTargetIds(postChange.getPersonId()+"");
			User user = userService.getById(postChange.getPersonId());
			List<String> userEhrList = new ArrayList<>();
			userEhrList.add(user.getEhr());
			notice.setTargetEhrs(StringUtil.join(userEhrList, "|"));
		}

		notice.setTitle(title);
		notice.setBusinessType("postchange");

		return sendNotice(notice);
	}

	@Override
	public boolean sendGoodsUseNotice(GoodsUse goodsUse, boolean isEdit) {
		//用戶1指派XXX請登入系統進行確認
		String title = "ORM-通知【使用及出入庫登記表】";
		if (isEdit){
			title += "更正：";
		}
		title += goodsUse.getFillingName() + "提交了使用及出入庫登記表，請登入系統進行確認。";

		NoticeVO notice = new NoticeVO();
		notice.setTitle(title);
		notice.setBusinessType("goodsuse");
		notice.setTargetIds(goodsUse.getPersonId()+"");
		User user = userService.getById(goodsUse.getPersonId());
		List<String> userEhrList = new ArrayList<>();
		userEhrList.add(user.getEhr());
		notice.setTargetEhrs(StringUtil.join(userEhrList, "|"));
		return sendNotice(notice);
	}

	@Override
	public boolean sendChecklistNotice(String cycle, Dept dept) {
		List<String> deptIds = new ArrayList<>();
		Dept parentDept = deptService.getById(dept.getParentId());
		if (parentDept.getOrgNo().startsWith("999")){
			deptIds.add(parentDept.getId() + "");
		}
		deptIds.add(dept.getId() + "");
		List<Role> roleList = roleService.getRolesByAlias("manager");
		List<String> roleIds = roleList.stream().map(role -> role.getId()+"").collect(Collectors.toList());
		List<User> users = userService.getUsersByDeptIdsRoleIds(deptIds, roleIds);
		List<String> userIds = users.stream().map(user -> user.getId() + "").collect(Collectors.toList());
		List<String> userEhrs = users.stream().map(user -> user.getEhr() + "").collect(Collectors.toList());
		List<String> userNames = users.stream().map(user -> user.getName() + "").collect(Collectors.toList());
		if (users.size() > 0){
			System.out.println(dept.getDeptName() + ":" + StringUtil.join(userNames));
		}

		String checkType = "每月";
		if (cycle.equals("day")){
			checkType = "每日";
		}else if (cycle.equals("week")){
			checkType = "每週";
		}

		String hangxinSend = paramService.getValue("notice." + cycle);

		String title = "ORM-通知【核對記錄表】" + dept.getDeptName() + "尚未完成" + checkType + "核對工作";
		NoticeVO notice = new NoticeVO();
		notice.setSendHangxin("true".equals(hangxinSend));
		notice.setTitle(title);
		notice.setBusinessType("checklist");
		notice.setDeptId(dept.getId() + "");
		notice.setRoleId(StringUtil.join(roleIds));
		notice.setTargetIds(StringUtil.join(userIds));
		notice.setTargetEhrs(StringUtil.join(userEhrs,"|"));
		return sendNotice(notice);
	}

	private String getCategoryName(KeyPwd keyPwd){
		List<String> categoryStrList = new ArrayList<>();
		String[] categorys = keyPwd.getCategory().split(",");
		for (int i = 0; i < categorys.length; i++) {
			String category = categorys[i];
			String value = dictService.getValue("key_type", category);
			String[] split = category.split("_");
			String key_type = dictService.getValue("key_type", split[0] + "_" + split[1] + "_" + split[2]);
			categoryStrList.add(key_type + "-" + value);
		}
		return StringUtil.join(categoryStrList, " | ");

		/*String category = keyPwd.getCategory();
		String value = dictService.getValue("key_type", category);
		String[] split = category.split("_");
		String key_type = dictService.getValue("key_type", split[0] + "_" + split[1] + "_" + split[2]);
		return key_type + "-" + value;*/
	}


}
