package com.gci.boot.modules.projects.controller;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gci.boot.common.util.QueryWrapperUtil;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.exception.GciBootException;
import com.gci.boot.modules.driver.vo.DriverUserVo;
import com.gci.boot.modules.projects.entity.ProjectUserRel;
import com.gci.boot.modules.projects.mapper.ProjectUserRelMapper;
import com.gci.boot.modules.projects.mapper.ProjectsMapper;
import com.gci.boot.modules.system.entity.SysUser;
import com.gci.boot.modules.system.service.ISysUserService;
import com.gci.boot.modules.system.vo.LoginUser;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gci.boot.annotation.Query.handle.QueryGenerator;
import com.gci.boot.annotation.permission.DataPermission;
import com.gci.boot.common.log.annotation.AddSysLog;
import com.gci.boot.common.util.JsonUtil;
import com.gci.boot.common.vo.Result;
import com.gci.boot.modules.projects.entity.Projects;
import com.gci.boot.modules.projects.service.IProjectsService;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 项目基础信息表 前端控制器
 * </p>
 *
 * @author xushuhan
 * @since 2023-08-25
 */
@Slf4j
@RestController
@RequestMapping("/projects/projects")
public class ProjectsController {

	@Autowired
	private IProjectsService projectsService;
	@Autowired
	private ISysUserService sysUserService;
	@Autowired
	private ProjectUserRelMapper projectUserRelMapper;
	@Autowired
	private ProjectsMapper projectsMapper;


	@AddSysLog(value = "项目档案-列表查询")
	@GetMapping("/list")
	@DataPermission(item="A.projectId", sqlIds = {"com.gci.boot.modules.projects.mapper.ProjectsMapper.getAllProjects"})
	public Result<?> list(Projects item) {
		List<Projects> list = projectsMapper.getAllProjects();
		return Result.ok(list);
	}

	@AddSysLog(value = "项目档案-分页查询")
	@GetMapping("/page")
	@DataPermission(item="A.projectId", sqlIds = {"com.gci.boot.modules.projects.mapper.ProjectsMapper.getPage"})
	public Result<?> page(Projects item,@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
						  @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {

		LambdaQueryWrapper<Projects> queryWrapper = QueryGenerator.initQueryWrapper(Projects.class, item);
		queryWrapper.eq(Projects::getDelFlag,0);
		queryWrapper.orderByDesc(Projects::getCreateTime);
		Page<Projects> page = new Page<Projects>(pageNo, pageSize);
//		IPage<Projects> pageList = projectsService.page(page,queryWrapper);
		//配合注释做数据权限
		IPage<Projects> pageList = projectsService.getPage(page,queryWrapper);
		for(Projects pro:pageList.getRecords()) {
			projectsService.initBusId(pro);
			projectsService.initUserId(pro);
			pro.setVehicleNum(projectsService.getVehicleTypeNumStr(pro.getBusIds()));
			SysUser sysUser = sysUserService.getByUsername(pro.getCreateBy());
			if(ObjectUtil.isNotNull(sysUser)){
				pro.setCreateUserId(sysUser.getId());
			}
		}
		return Result.ok(pageList);
	}

	@AddSysLog(value = "项目档案-新增")
	@PostMapping("/add")
	public Result<?> add(@RequestBody Projects item){
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		if(StrUtil.isBlank(item.getUserIds())){
			return Result.error(101,"项目成员必须包含当前创建人!");
		}else{
			if(!item.getUserIds().contains(sysUser.getId())){
				return Result.error(101,"项目成员必须包含当前创建人!");
			}

		}
		projectsService.saveItem(item,sysUser.getUsername());
		return Result.ok();
	}

	@AddSysLog(value = "项目档案-编辑")
	@PutMapping("/edit")
	public Result<?> edit(@RequestBody Projects item){
		Projects projects = projectsService.getById(item.getId());
		SysUser sysUser = sysUserService.getByUsername(projects.getCreateBy());
		if(StrUtil.isBlank(item.getUserIds())){
			return Result.error(101,"项目成员必须包含当前创建人!");
		}else{
			if(Objects.nonNull(sysUser) && !item.getUserIds().contains(sysUser.getId())){
				return Result.error(101,"项目成员必须包含当前创建人!");
			}

		}
		log.info("---项目基础信息edit-----"+JsonUtil.object2Json(item));
		projectsService.saveItem(item,sysUser.getUsername());
		return Result.ok();
	}

	@AddSysLog(value = "项目档案-删除")
	@DeleteMapping("/delete")
	public Result<?> delete(Projects item){
		if (item.getId().equals(CommonConstant.INNER_PROJECT)) {
			throw new GciBootException("默认项目无法删除！");
		}
		projectsService.removeById(item.getId());
		return Result.ok();
	}

	/**
	 * 启用禁用
	 * @param item
	 * @return
	 */
	@PostMapping("/updateStatus")
	public Result<?> updateStatus(@RequestBody Projects item){
		LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
		projectsService.updateStatus(item, sysUser.getUsername());
		return Result.ok();
	}

	/**
	 *  simpleWrite在数据量不大的情况下可以使用（5000以内，具体也要看实际情况），数据量大时要 重复多次写入
	 * @param response
	 */
	@AddSysLog(value = "项目档案-导出")
	@GetMapping("/simple/export")
	@DataPermission(item="A.projectId", sqlIds = {"com.gci.boot.modules.projects.mapper.ProjectsMapper.getPage"})
	public Result<?> export(Projects item,HttpServletResponse response){
		try (OutputStream output = response.getOutputStream()){

			String fileName = "项目基础信息.xlsx";
			try {
				fileName = URLEncoder.encode(fileName, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);


			Result<IPage<Projects>> result = (Result<IPage<Projects>>)page(item,1,20000);
			List<Projects> list = result.getResult().getRecords();

			EasyExcel.write(output, Projects.class).sheet("sheet1").doWrite(list);
			//EasyExcel.write(output, Projects.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("sheet1").doWrite(list);

		} catch (IOException e) {
			log.error(e.getMessage(), e);
			return Result.error("导出错误！");
		}
		return Result.ok();
	}

	@AddSysLog(value = "项目档案-分页导出")
	@GetMapping("/multi/export")
	@DataPermission(item="A.projectId", sqlIds = {"com.gci.boot.modules.projects.mapper.ProjectsMapper.getPage"})
	public Result<?> multiExport(Projects item,HttpServletResponse response){
		try (OutputStream output = response.getOutputStream()){
			String fileName = "项目基础信息.xlsx";
			try {
				fileName = URLEncoder.encode(fileName, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);

			int pages = 1;
			try (ExcelWriter excelWriter = EasyExcel.write(output, Projects.class).build()) {
				WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").build();
				for (int i = 0; i < pages; i++) {
					Result<?> result = page(item,i+1, 10);
					IPage<Projects> page = (IPage<Projects>)result.getResult();
					List<Projects> data = page.getRecords();
					int temp = (int)page.getPages();
					if(pages<temp) {
						pages = temp;
					}
					excelWriter.write(data, writeSheet);
				}
			}
		} catch (IOException e) {
			log.error(e.getMessage(), e);
			return Result.error("导出错误！");
		}
		return Result.ok();
	}


	/**
	 * 多次读入
	 * @param request
	 * @return
	 */
	@AddSysLog(value = "项目档案-导入")
	@PostMapping("/simple/import")
	public Result<?> simpleImport(HttpServletRequest request) {
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
		for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
			MultipartFile file = entity.getValue();// 获取上传文件对象
			try(InputStream input = file.getInputStream()) {
				List<Projects> list = EasyExcel.read(input).head(Projects.class).sheet().doReadSync();
				log.info("数据量：{}",list.size());
				projectsService.saveBatch(list);
			}catch (IOException e){
				log.error(e.getMessage(), e);
				return Result.error("导入错误！");
			}
		}
		return Result.ok();
	}

	@AddSysLog(value = "项目档案-获取项目成员")
	@GetMapping("/getUserByProjectId")
	public Result<?> getUserByProjectId(String projectId,
										@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
										@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
		List<SysUser> list = new ArrayList<>();
		if(StrUtil.isBlank(projectId)){
			return Result.error(101,"项目id不能为空!");
		}
		QueryWrapper<ProjectUserRel> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("project_id", projectId);
		List<ProjectUserRel> projectUserRelList = projectUserRelMapper.selectList(queryWrapper);
		if(CollectionUtil.isNotEmpty(projectUserRelList)){
			List<String> userIds = projectUserRelList.stream().map(ProjectUserRel::getUserId).collect(Collectors.toList());
			if(CollectionUtil.isNotEmpty(userIds)){
//				LambdaQueryWrapper<SysUser> userQueryWrapper = new LambdaQueryWrapper<>();
//				userQueryWrapper.in(SysUser::getId,userIds);
//				list = sysUserService.list(userQueryWrapper);
				SysUser user = new SysUser();
				LambdaQueryWrapper<SysUser> userQueryWrapper = QueryGenerator.initQueryWrapper(SysUser.class, user);
				userQueryWrapper.in(SysUser::getId,userIds);
				Page<SysUser> page = new Page<SysUser>(pageNo, pageSize);
				IPage<SysUser> pageList = sysUserService.page(page,userQueryWrapper);

				// 处理等保解密数据
				Iterator<SysUser> userIterator = pageList.getRecords().iterator();
				while (userIterator.hasNext()) {
					SysUser sysUser = userIterator.next();
					sysUser.setPhone(sysUserService.processPhone(sysUser));
				}
				return Result.ok(pageList);
			}
		}

		return Result.ok(null);
	}
}
