package com.yeejoin.precontrol.controller;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.liangbaika.validate.annations.ValidateParam;
import com.github.liangbaika.validate.annations.ValidateParams;
import com.github.liangbaika.validate.enums.Check;
import com.yeejoin.precontrol.common.annotations.OpsLog;
import com.yeejoin.precontrol.common.constant.Constant;
import com.yeejoin.precontrol.common.dto.CommonPageableDto;
import com.yeejoin.precontrol.common.dto.CompanyDto;
import com.yeejoin.precontrol.common.dto.CompanyblackDto;
import com.yeejoin.precontrol.common.entity.Company;
import com.yeejoin.precontrol.common.entity.CompanyAcount;
import com.yeejoin.precontrol.common.entity.CompanyBusiness;
import com.yeejoin.precontrol.common.entity.CompanyQualifications;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.entity.ProjectCompany;
import com.yeejoin.precontrol.common.enums.OpsLogEnum;
import com.yeejoin.precontrol.common.enums.SmallProPageEnum;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.exception.errorEnum.BaseExceptionEnum;
import com.yeejoin.precontrol.common.param.CompanyParam;
import com.yeejoin.precontrol.common.publish.TranslateEventPublish;
import com.yeejoin.precontrol.common.service.ICompanyAcountService;
import com.yeejoin.precontrol.common.service.ICompanyBusinessService;
import com.yeejoin.precontrol.common.service.ICompanyQualificationAttachmentService;
import com.yeejoin.precontrol.common.service.ICompanyQualificationService;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IDistrictsService;
import com.yeejoin.precontrol.common.service.IPersonAscriptionService;
import com.yeejoin.precontrol.common.service.IProjectCompanyService;
import com.yeejoin.precontrol.common.service.IStatisticsService;
import com.yeejoin.precontrol.common.service.SmallProService;
import com.yeejoin.precontrol.common.utils.CommonResponseUtil;
import com.yeejoin.precontrol.common.utils.FileHelper;
import com.yeejoin.precontrol.common.utils.PlatformUtils;
import com.yeejoin.precontrol.common.vo.BadCompanyVo;
import com.yeejoin.precontrol.common.vo.ReginParams;
import com.yeejoin.precontrol.controller.publics.BaseController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;

/**
 * 企业基本信息
 *
 * @author duanwei
 * @date 2020-06-30
 */
@RestController
@Api(tags = "企业基本信息Api")
@RequestMapping(value = "/company", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Slf4j
public class CompanyController extends BaseController {

	/**
	 * 企业服务
	 */
	@Autowired
	ICompanyService iCompanyService;
	/**
	 * 企业账户服务
	 */
	@Autowired
	ICompanyAcountService iCompanyAcountService;
	/**
	 * 小程序服务
	 */
	@Autowired
	SmallProService smallProService;
	/**
	 * 企业工商服务
	 */
	@Autowired
	ICompanyBusinessService iBusinessService;
	/**
	 * 企业资质服务
	 */
	@Autowired
	ICompanyQualificationService iCompanyQualificationService;

	/**
	 * 企业资质服务附件
	 */
	@Autowired
	ICompanyQualificationAttachmentService qualificationAttachService;
	/**
	 * 省市区服务
	 */
	@Autowired
	IDistrictsService districtsService;
	/**
	 * 翻译事件推送服务
	 */
	@Autowired
	TranslateEventPublish translateEventPublish;

	@Autowired
	PlatformUtils platformUtils;

	@Autowired
	IStatisticsService statisticsService;

	@Autowired
	IProjectCompanyService iProjectCompanyService;

	@Autowired
	IPersonAscriptionService iPersonAscriptionService;

	/**
	 * 新增企业基本信息
	 *
	 * @return
	 */
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ApiOperation(httpMethod = "POST", value = "新增企业基本信息", notes = "新增企业基本信息")
	@Transactional
	public Object saveCompany(@RequestBody @Valid CompanyDto companyDto) {
		Company company = iCompanyService.saveOrUpdateCompany(companyDto);
		translateEventPublish.publish(company);
		statisticsService.initWs("0", Constant.WS_COMPOSITESUM);
		return true;
	}

	/**
	 * 根据id删除
	 *
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
	@ApiOperation(httpMethod = "DELETE", value = "根据id删除", notes = "根据id删除")
	public Object deleteById(HttpServletRequest request, @PathVariable Long id) {
		HashMap filters = new HashMap<String, Long>();
		filters.put("company_id", id);
		try {
			iBusinessService.removeByMap(filters);
			iCompanyQualificationService.removeByMap(filters);
			iCompanyService.removeById(id);
			iCompanyAcountService.removeByMap(filters);
			statisticsService.initWs("0", Constant.WS_COMPOSITESUM);
			return true;
		} catch (Exception e) {
			return CommonResponseUtil.failure(e.getMessage());
		}
	}

	/**
	 * 根据ids删除
	 *
	 * @param ids
	 * @return
	 */
	@RequestMapping(value = "/ids/{ids}", method = RequestMethod.DELETE)
	@ApiOperation(httpMethod = "DELETE", value = "根据ids删除", notes = "根据ids删除")
	@OpsLog(value = OpsLogEnum.DELETE_COMPANY)
	public Object deleteByIds(HttpServletRequest request, @PathVariable String ids) {
		if (StringUtils.isNotBlank(ids)) {
			String[] idsSplit = ids.split(",");
			Set<Long> comIds = Arrays.stream(idsSplit).map(Long::parseLong).collect(Collectors.toSet());
			int count = iProjectCompanyService
					.count(new LambdaQueryWrapper<ProjectCompany>().in(ProjectCompany::getCompanyId, comIds));
			if (count > 0) {
				throw new BaseException("所选分包商存在关联项目,无法删除");
			}
			int acount = iPersonAscriptionService
					.count(new LambdaQueryWrapper<PersonAscription>().in(PersonAscription::getCompanyId, comIds));
			if (acount > 0) {
				throw new BaseException("所选分包商存在关联人员,无法删除");
			}
			// 工商信息
			iBusinessService
					.remove(new QueryWrapper<CompanyBusiness>().lambda().in(CompanyBusiness::getCompanyId, comIds));
			// 资质信息
			iCompanyQualificationService.remove(
					new QueryWrapper<CompanyQualifications>().lambda().in(CompanyQualifications::getCompanyId, comIds));
			// 银行账户
			iCompanyAcountService
					.remove(new LambdaQueryWrapper<CompanyAcount>().in(CompanyAcount::getCompanyId, comIds));
			iCompanyService.removeByIds(comIds);
			return true;
		} else {
			throw new BaseException(BaseExceptionEnum.PARAMETER_ERROR);
		}
	}

	/**
	 * 导入分包商信息
	 *
	 * @return
	 */
	@RequestMapping(value = "/import", method = RequestMethod.POST)
	@ApiOperation(httpMethod = "POST", value = "导入分包商信息", notes = "导入分包商信息")
	public Object companyImport(
			@ApiParam(value = "导入数据文件", required = true) @RequestBody(required = true) MultipartFile file)
			throws Exception {
		String fileName = file.getOriginalFilename();
		if (!fileName.endsWith(".xls")) {
			throw new BaseException("文件格式错误");
		}
		iCompanyService.companyImport(file);
		return true;
	}

	/**
	 * 修改企业基本信息
	 *
	 * @return
	 */
	@ValidateParams(value = {
			@ValidateParam(value = Check.le, express = "50", argName = "companyDto.companyBusiness.companyAddress"),
			@ValidateParam(value = Check.le, express = "200", argName = "companyDto.companyBusiness.businessScope") })
	@RequestMapping(value = "/updateById", method = RequestMethod.PUT)
	@OpsLog(value = OpsLogEnum.EDIT_COMPANY)
	@ApiOperation(httpMethod = "PUT", value = "修改企业基本信息", notes = "修改企业基本信息")
	public Object updateByIdCompany(@RequestBody @Valid CompanyDto companyDto) {
		Company company = iCompanyService.saveOrUpdateCompany(companyDto);
		translateEventPublish.publish(company);
		return true;
	}

	/**
	 * 根据id查询
	 *
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据id查询", notes = "根据id查询")
	public Object selectById(@PathVariable Long id) {
		return iCompanyService.selectById(id);
	}

	/**
	 * 列表分页查询
	 *
	 * @return
	 */
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "列表分页查询", notes = "列表分页查询")
	public Object listPage(CommonPageableDto pageable, CompanyParam param, String ids) {
		if (StringUtils.isNotBlank(ids)) {
			String[] idsSplit = ids.split(",");
			Set<Long> queryIds = Arrays.stream(idsSplit).map(Long::parseLong).collect(Collectors.toSet());
			if (queryIds != null || queryIds.size() > 0) {
				param.setIds(queryIds);
			}
		}
		getUserInfo();
		ReginParams reginInfo = getReginInfo();
		if (isFbsRole(reginInfo)) {
			Company company = reginInfo.getCompany();
			if (company != null) {
				Long companyId = company.getId();
				param.setId(companyId);
			}
		}
		if (param.getIsAllCode()) {
			param.setOrgCode(null);
		}
		return iCompanyService.pageInfo(pageable, param);
	}

	/**
	 * 公司二维码
	 *
	 * @return
	 */
	@RequestMapping(value = "/companyQrCode", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "公司二维码", notes = "公司二维码")
	public void companyQrCode(HttpServletResponse response, @RequestParam(required = true) Long companyId, Long size,
			@RequestParam(value = "type", required = false, defaultValue = "png") String type) {
		String smallProToken = smallProService.getSmallProToken();
		String scene = companyId.toString();
		Company company = iCompanyService.getById(companyId);
		if (company != null) {
			String fileName = companyId.toString();
			String page = SmallProPageEnum.companyDetail.getPath();
			smallProService.getSmallProQrCodeResponse(smallProToken, scene, page, size, false, null, false, response,
					fileName, type);
		} else {
			throw new BaseException("该公司不存在");
		}
	}

	/**
	 * 公司下拉框
	 *
	 * @return
	 */
	@RequestMapping(value = "/companySelect", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "公司列表下拉框", notes = "公司下拉框")
	public Object companySelect() {
		return iCompanyService.companySelect();
	}

	/**
	 * 黑名单操作
	 *
	 * @return
	 */
	@RequestMapping(value = "/blacklist/operation", method = RequestMethod.POST)
	@ApiOperation(httpMethod = "POST", value = "黑名单操作", notes = "黑名单操作")
	@Transactional
	public Object blacklistOperation(@RequestBody CompanyblackDto blackDto) {
		Company company = iCompanyService.getById(blackDto.getId());
		if (company != null) {
			company.setInBlackList(blackDto.getInBlackList());
			iCompanyService.updateById(company);
			return true;
		} else {
			return CommonResponseUtil.failure("所选公司不存在！");
		}
	}

	/**
	 * 首页违章项目
	 *
	 * @return
	 */
	@RequestMapping(value = "/badCompany", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "首页违章分包商", notes = "首页违章分包商")
	public Object badCompany(@ApiParam(value = "是否查询所有违章和0违章", required = false) boolean isAllStatus,
			@ApiParam(value = "是否0违章", required = true) boolean isBad,
			@ApiParam(value = "分页") CommonPageableDto pageable, @ApiParam(value = "查询参数") BadCompanyVo badCompanyVo,
			@ApiParam(value = "类型 0查询列表 1 导出列表") @RequestParam Long operType, HttpServletResponse response) {
		String fileName = UUID.randomUUID().toString() + ".xls";
		String title = isAllStatus ? "分包商信息" : isBad ? "违章分包商信息" : "0违章分包商信息";
		badCompanyVo.setOrgCode(platformUtils.getOrgCode());
		if (badCompanyVo.getKey() != null) {
			switch (badCompanyVo.getKey()) {
			case "scale":
				if ("asc".equals(badCompanyVo.getSortType())) {
					badCompanyVo.setScaleOrder(true);
				} else {
					badCompanyVo.setScaleOrder(false);
				}
				break;
			case "count":
				if ("asc".equals(badCompanyVo.getSortType())) {
					badCompanyVo.setCountOrder(true);
				} else {
					badCompanyVo.setCountOrder(false);
				}
				break;
			case "money":
				if ("asc".equals(badCompanyVo.getSortType())) {
					badCompanyVo.setMoneyOrder(true);
				} else {
					badCompanyVo.setMoneyOrder(false);
				}
				break;
			default:
				badCompanyVo.setScaleOrder(false);
			}
		} else {
			badCompanyVo.setScaleOrder(false);
		}
		IPage<BadCompanyVo> page = iCompanyService.pageBadCompany(isBad, isAllStatus, pageable, badCompanyVo);
		if (operType == 1) {
			List<BadCompanyVo> excelList = page.getRecords();
			FileHelper.exportExcel(excelList, title, title, BadCompanyVo.class, fileName, response);
			return null;
		} else {
			return page;
		}
	}

	/**
	 * 根据分包商查询部门以及账户信息
	 *
	 * @return
	 */
	@RequestMapping(value = "/deptQueryWithAccount", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据分包商查询部门以及账户信息", notes = "根据分包商查询部门以及账户信息")
	public Object deptQueryWithAccount(Long companyId) {
		return iCompanyService.deptQueryWithAccount(companyId);
	}

	/**
	 * 根据分包商查询部门 （查询人员 分两步 写成2个接口的原因是平台调用的接口是两个）
	 *
	 * @return
	 */
	@RequestMapping(value = "/deptQuery", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据分包商查询部门", notes = "根据分包商查询部门")
	public Object deptQuery(Long companyId, String roleName, Long projectId) {
		return iCompanyService.deptQuery(companyId, roleName, projectId);
	}

	/**
	 * 根据部门查询班组
	 *
	 * @return
	 */
	@RequestMapping(value = "/teamQuery", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "根据部门查询班组", notes = "根据部门查询班组")
	public Object teamQuery(Long deptId, String roleName, Long projectId) {
		return iCompanyService.teamQuery(deptId, roleName, projectId);
	}

	/**
	 * 根据部门查询班组
	 *
	 * @return
	 */
	@RequestMapping(value = "/platDeptQuery", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "平台部门树", notes = "平台部门树")
	public Object platDeptQuery(String orgCode,Boolean noFbs) {
		return iCompanyService.platDeptQuery(orgCode,noFbs);
	}

	/**
	 * 根据登陆人查询分包商
	 *
	 * @return
	 */
	@RequestMapping(value = "/byOrgCode", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "项目部分包商", notes = "项目部分包商")
	public Object byOrgCode() {
		String orgCode = platformUtils.getOrgCode();
		return iCompanyService.getByOrgCode(orgCode);
	}

	/**
	 * 根据平台分包商部门查询分包商
	 *
	 * @return
	 */
	@RequestMapping(value = "/byPlatFbsDeptOrgCode", method = RequestMethod.GET)
	@ApiOperation(httpMethod = "GET", value = "项目部分包商", notes = "项目部分包商")
	public Object byPlatFbsDeptOrgCode(String orgCode) {
		return iCompanyService.byPlatFbsDeptOrgCode(orgCode);
	}
}
