package digital.laboratory.platform.imr.controller;

import cn.hutool.core.io.file.FileNameUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.log.annotation.SysLog;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.imr.dto.QueryStorageDTO;
import digital.laboratory.platform.imr.entity.StorageCell;
import digital.laboratory.platform.imr.entity.StorageCupboard;
import digital.laboratory.platform.imr.entity.StorageRoom;
import digital.laboratory.platform.imr.mapper.StorageCellMapper;
import digital.laboratory.platform.imr.mapper.StorageCupboardMapper;
import digital.laboratory.platform.imr.service.StorageCupboardService;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import digital.laboratory.platform.common.oss.service.OssFile;

import static com.alibaba.fastjson.util.IOUtils.stringSize;

/**
 * 
 *
 * @author Zhang Xiaolong created at  2023-03-17
 * @describe  前端控制器
 *
 * 这是与表示层的接口, 不应该接业务逻辑写在这里, 业务逻辑应该写在 service 中
 * 这里写什么:
 *     为前端提供数据, 接受前端的数据
 *     为前端提供的数据, 从 service 取得后, 可以做一些适当的加工, 这种加工不是业务层面的, 只能是数据格式上, 为方便前端处理
 *     接受前端的数据, 每一个函数的参数可以先做一些整理后, 再调用 service 中的函数。这里对参数的整理, 应该只是格式上的, 而不能是业务上的
 * 数据层在 mapper 中, 数据层不涉及业务, 只管技术上的 对象<->表 之间的转换
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/storage_cupboard" )
@Api(value = "storage_cupboard", tags = "柜子管理")
public class StorageCupboardController {

    private final  StorageCupboardService storageCupboardService;


	private final StorageCupboardMapper cupboardMapper;


	private final StorageCellMapper cellMapper;

	private final OssFile ossFile;

	/**
	 * 通过id查询
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id查询", notes = "通过id查询")
	@GetMapping("/{id}" )
	@PreAuthorize("@pms.hasPermission('imr_storage_cupboard_get')" )
	public R<StorageCupboard> getById(@PathVariable("id" ) String id, HttpServletRequest theHttpServletRequest) {
		Principal principal = theHttpServletRequest.getUserPrincipal();
		DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        StorageCupboard storageCupboard = storageCupboardService.getById(id);
		return R.ok(storageCupboard);
		//return R.ok(storageCupboardService.getById(id));
	}






	@ApiOperation(value = "柜子列表查询接口--存储管理", notes = "柜子列表查询接口--存储管理")
	@GetMapping("/cupboard/list" )
	//@PreAuthorize("@pms.hasPermission('imr_storage_room_get')" )
	public R<IPage<StorageCupboard>> getStorageRoomPage(QueryStorageDTO dto){


		Page<StorageCupboard> page = new Page<>(dto.getCurrent(),dto.getSize());

		IPage<StorageCupboard> storageCupboardList = cupboardMapper.getStorageCupboardPage(page,Wrappers.<StorageCupboard>query()
				.eq(!dto.getId().isEmpty(),"id",dto.getId())
				.orderByDesc("create_time")
		);
		return R.ok(storageCupboardList,"查询成功");
	}



/*	@ApiOperation(value = "修改--上传柜子图片", notes = "修改--上传柜子图片")
	@PostMapping(value = "/uploadCupboard/{cupboardId}")
	//@PreAuthorize("@pms.hasPermission('roomUpload')")
	public R uploadAttachmentObj(@PathVariable("cupboardId") String cupboardId, @RequestPart("file") MultipartFile file) throws Exception {

		StorageCupboard storageCupboard = cupboardMapper.selectById(cupboardId);
		if (storageCupboard != null) {

			String path = "cupboard" + "/" + cupboardId;
			String fileName = FileNameUtil.getName(file.getOriginalFilename());
			boolean r = ossFile.fileUpload(file, path);
			Map<String, String> ResultData = new HashMap<>();
			ResultData.put("fileName", fileName);
			ResultData.put("path", path);

			if (r) {
				//修改数据库
				storageCupboard.setCupboardPhoto(path);
				storageCupboard.setFileName(fileName);
				cupboardMapper.updateById(storageCupboard);
				return R.ok(ResultData, "上传成功");
			}
			return R.failed("上传失败");
		}
		return R.failed(null, "这个柜子不存在");
	}*/


	/**
	 * 新增
	 * @param storageCupboard
	 * @return R
	 */
	@ApiOperation(value = "添加存储柜--存储管理", notes = "添加存储柜--存储管理")
	@SysLog("添加存储柜--存储管理" )
	@PostMapping("/createStorageCupboard")
	//@PreAuthorize("@pms.hasPermission('imr_storage_room_add')" )
	public R<StorageCupboard> postAddObject(StorageCupboard storageCupboard, HttpServletRequest theHttpServletRequest,@RequestPart(value = "file",required = false) MultipartFile file)throws Exception {
		Principal principal = theHttpServletRequest.getUserPrincipal();
		DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

		if (storageCupboard.getRoomId() == null) {
			throw new RuntimeException(String.format("柜子必须关联格子"));
		}
		if (storageCupboard.getSpecifications() == null) {
			throw new RuntimeException(String.format("柜子必须要填写规格"));
		}
		if (storageCupboard.getCupboardNo() == null) {
			throw new RuntimeException(String.format("柜子编号不能为空"));
		}

		storageCupboard.setId(IdWorker.get32UUID().toUpperCase());

		if (file != null) {
			String path = "cupboard" + "/" + storageCupboard.getId();
			String fileName = FileNameUtil.getName(file.getOriginalFilename());
			boolean r = ossFile.fileUpload(file, path);
			if (r) {
				storageCupboard.setCupboardPhoto(path);
				storageCupboard.setFileName(fileName);
				cupboardMapper.insert(storageCupboard);
				//根据柜子规格创建格子
				for (Integer a = 1; a <= storageCupboard.getSpecifications(); a++) {
					StorageCell storageCell = new StorageCell();
					storageCell.setId(IdWorker.get32UUID().toUpperCase());
					storageCell.setStatus(true);//默认未存入东西
					storageCell.setCupboardId(storageCupboard.getId());
					//取柜子的编号前几位
					String head = storageCupboard.getCupboardNo().substring(0, 3);
					//制定格子编号生成规则
					String str = "CL";
					String number = getNumber(a);
					storageCell.setCellNo(str + head + number);
					cellMapper.insert(storageCell);
				}
				return R.ok(storageCupboard, "创建成功");
			} else {
				//删除图片
				ossFile.fileDelete("cupboard" + "/" + storageCupboard.getId() + "/" + fileName);
				return R.failed("创建失败");
			}
		} else {
			cupboardMapper.insert(storageCupboard);
			return R.ok(storageCupboard, "创建成功");
		}
	}


		/**
		 * 修改
		 * @param storageCupboard
		 * @return R
		 */
		@ApiOperation(value = "修改--存储管理(数据修改+图片修改)", notes = "修改--存储管理")
		@SysLog("修改")
		@PutMapping("/updateCupboard")
		//@PreAuthorize("@pms.hasPermission('imr_storage_room_edit')" )
		public R<StorageCupboard> putUpdateById (StorageCupboard storageCupboard, HttpServletRequest
		theHttpServletRequest, @RequestPart(value = "file", required = false) MultipartFile file)throws Exception {
			Principal principal = theHttpServletRequest.getUserPrincipal();
			DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

			StorageCupboard cupboard = storageCupboardService.getById(storageCupboard.getId());//数据库数据

			if(cupboard==null){
				throw new RuntimeException(String.format("当前修改数据不存在"));
			}

			if ((int)storageCupboard.getSpecifications()!=(int)cupboard.getSpecifications()) {
				throw new RuntimeException(String.format("不允许修改"));
			}

			if (file != null) {
				String path = "cupboard" + "/" + storageCupboard.getId();
				String fileName = FileNameUtil.getName(file.getOriginalFilename());
				boolean r = ossFile.fileUpload(file, path);
				if (r) {
					storageCupboard.setCupboardPhoto(path);
					storageCupboard.setFileName(fileName);
					cupboardMapper.updateById(storageCupboard);
					return R.ok(storageCupboard, "修改成功");
				} else {
					return R.failed("修改失败");
				}
			} else {
				if(cupboard.getCupboardPhoto()!=null && cupboard.getFileName()!=null) {
					//删除图片
					ossFile.fileDelete("cupboard" + "/" + cupboard.getId() + "/" + cupboard.getFileName());
				}
				storageCupboard.setFileName(null);
				storageCupboard.setCupboardPhoto(null);
				cupboardMapper.updateById(storageCupboard);
				return R.ok(storageCupboard, "修改成功");
			}
		}

		/**
		 * 通过id删除
		 * @param id id
		 * @return R
		 **/
		@ApiOperation(value = "通过id删除柜子--存储管理", notes = "通过id删除柜子--存储管理")
		@SysLog("通过id删除")
		@DeleteMapping("deleteCupboard/{id}")
		//@PreAuthorize("@pms.hasPermission('imr_storage_room_del')" )
		public R<StorageCupboard> deleteById (@PathVariable String id, HttpServletRequest theHttpServletRequest) throws
		Exception {
			Principal principal = theHttpServletRequest.getUserPrincipal();
			DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

			QueryWrapper<StorageCell> wrapper = new QueryWrapper<>();
			wrapper.eq("cupboard_id", id);
			List<StorageCell> storageCells = cellMapper.selectList(wrapper);
			for (StorageCell storageCell : storageCells) {
				if (!storageCell.getStatus()) {
					throw new RuntimeException(String.format("当前柜子中"+storageCell.getCellNo()+"格子还存有物品"));
				}
			}
			//删除柜子
			StorageCupboard storageCupboard = storageCupboardService.getById(id);
			if (storageCupboard.getCupboardPhoto() != null && storageCupboard.getFileName() != null) {
				//删除图片
				ossFile.fileDelete("cupboard" + "/" + storageCupboard.getId() + "/" + storageCupboard.getFileName());
			}

			if (storageCupboardService.removeById(id)) {

				QueryWrapper<StorageCell> queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("cupboard_id",id);
				cellMapper.delete(queryWrapper);//删除格子
				//删除对应格子照片
				for (StorageCell storageCell : storageCells) {
					if (storageCell.getCellPhoto() != null && storageCell.getFileName() != null) {
						//删除图片
						ossFile.fileDelete("cell" + "/" + storageCell.getId() + "/" + storageCell.getFileName());
					}
				}
				return R.ok(storageCupboard, "对象删除成功");
			} else {
				return R.failed(storageCupboard, "对象删除失败");
			}

		}

		/**
		 * 通过柜子id和文件名获取图片"/getRoomPicture/{roomId}/{fileName}"
		 */
		@ApiOperation(value = "通过柜子id和文件名获取图片--存储管理", notes = "通过柜子id和文件名获取图片--存储管理")
		@GetMapping("/getCupboardPicture/{cupboardId}/{fileName}")
		//@PreAuthorize("@pms.hasPermission('imr_storage_room_get')" )
		public void getRoomPicture (@PathVariable("cupboardId") String cupboardId,
				@PathVariable("fileName") String fileName,
				HttpServletResponse httpServletResponse) throws Exception {
			StorageCupboard storageCupboard = storageCupboardService.getById(cupboardId);
			if (storageCupboard == null) {
				throw new RuntimeException(String.format("当前柜子数据不存在"));
			}
			ossFile.fileGet("cupboard" + "/" + storageCupboard.getId() + "/" + fileName, httpServletResponse.getOutputStream());
			httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(storageCupboard.getFileName()));
		}


		/**
		 *
		 * @param
		 * @return
		 **/
		@ApiOperation(value = "柜子列表查询--下拉框的", notes = "柜子列表查询--下拉框的")
		@GetMapping("/list/{roomId}")
		//@PreAuthorize("@pms.hasPermission('imr_storage_room_get')" )
		public R<List<StorageCupboard>> getStorageRoomList (@PathVariable("roomId") String roomId ){

			List<StorageCupboard> storage = cupboardMapper.getStorageCupboardList(Wrappers.<StorageCupboard>query()
					.eq("room_id", roomId)
					.ne("status", 0)//排除不可用的柜子
					.orderByDesc("sort")
			);
			return R.ok(storage, "查询成功");
		}




	public  static String getNumber(Integer a){
		String number  = "";
		Integer i = stringSize(a);
		if(i==1){
			number="000"+a.toString();
		}else if(i==2){
			number="00"+a.toString();
		}else if(i==3){
			number="0"+a.toString();
		}

		return number;
	}










}
