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.constant.OSSDirectoryConstants;
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.entity.StorageCupboard;
import digital.laboratory.platform.imr.entity.StorageRoom;
import digital.laboratory.platform.imr.mapper.StorageCupboardMapper;
import digital.laboratory.platform.imr.mapper.StorageRoomMapper;
import digital.laboratory.platform.imr.service.StorageRoomService;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.common.core.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
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;


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



	private final StorageRoomMapper roomMapper;

    private final  StorageRoomService storageRoomService;



	private final StorageCupboardMapper cupboardMapper;

	private final OssFile ossFile;






/*	@ApiOperation(value = "上传房间图片", notes = "上传房间图片")
	@PostMapping(value = "/uploadRoom/{roomId}")
	@PreAuthorize("@pms.hasPermission('roomUpload')")
	public R uploadAttachmentObj(@PathVariable("roomId") String roomId, @RequestPart("file") MultipartFile file) throws Exception {

		StorageRoom storageRoom = roomMapper.selectById(roomId);
		if (storageRoom != null) {

			String path = "room" + "/" + roomId;
			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) {
				//修改数据库
				storageRoom.setRoomPhoto(path);
				storageRoom.setFileName(fileName);
				roomMapper.updateById(storageRoom);
				return R.ok(ResultData, "上传成功");
			}
			return R.failed("上传失败");
		}
		return R.failed(null, "这个房间不存在");
	}*/




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

        StorageRoom storageRoom = storageRoomService.getById(id);
		return R.ok(storageRoom);
		//return R.ok(storageRoomService.getById(id));
	}

	/**
     * 分页查询
     * @param roomName
     * @return
     */
    @ApiOperation(value = "存储室列表查询接口--存储管理", notes = "存储室列表查询接口--存储管理")
    @GetMapping("/room/list" )
    //@PreAuthorize("@pms.hasPermission('imr_storage_room_get')" )
    public R<List<StorageRoom>> getStorageRoomPage(String roomName){

		List<StorageRoom> storageRoomList = roomMapper.getStorageRoomPage(Wrappers.<StorageRoom>query()
				.like(!roomName.isEmpty(),"name",roomName)
				.orderByDesc("create_time")
		);
		return R.ok(storageRoomList,"查询成功");
    }

	/**
	 * 新增
	 * @param storageRoom
	 * @return R
	 */
	@ApiOperation(value = "添加存储室--存储管理(上传或不上传图片)", notes = "添加存储室--存储管理")
	@SysLog("添加存储室" )
	@PostMapping("/createStorageRoom")
	//@PreAuthorize("@pms.hasPermission('imr_storage_room_add')" )
	public R<StorageRoom> postAddObject(StorageRoom storageRoom, HttpServletRequest theHttpServletRequest,@RequestPart(value = "file",required = false) MultipartFile file)throws Exception {
		Principal principal = theHttpServletRequest.getUserPrincipal();
		DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();


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

		if(file!=null){
			String path = "room" + "/" + storageRoom.getId();
			String fileName = FileNameUtil.getName(file.getOriginalFilename());
			boolean r = ossFile.fileUpload(file, path);
			if (r) {
				storageRoom.setRoomPhoto(path);
				storageRoom.setFileName(fileName);
				roomMapper.insert(storageRoom);
				return R.ok(storageRoom, "创建成功");
			}
			else {
				//删除图片
				ossFile.fileDelete("room" + "/" + storageRoom.getId() + "/" + fileName);
				return R.failed("创建失败");
			}
		}else {
			roomMapper.insert(storageRoom);
			return R.ok(storageRoom, "创建成功");
		}
	}





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


		StorageRoom room = roomMapper.selectById(storageRoom.getId());
		if(room==null){
			throw new RuntimeException(String.format("存储室数据不存在"));
		}
		if(file!=null){
			String path = "room" + "/" + storageRoom.getId();
			String fileName = FileNameUtil.getName(file.getOriginalFilename());
			boolean r = ossFile.fileUpload(file, path);
			if (r) {
				storageRoom.setRoomPhoto(path);
				storageRoom.setFileName(fileName);
				roomMapper.updateById(storageRoom);
				return R.ok(storageRoom, "修改成功");
			}
			else {
				return R.failed("修改失败");
			}
		}else {
			//判断数据库是否存储照片
			if(room.getRoomPhoto() != null && room.getFileName()!=null){
				//删除图片
				ossFile.fileDelete("room" + "/" + room.getId() + "/" + room.getFileName());
			}
			//修改数据
			storageRoom.setFileName("");
			storageRoom.setRoomPhoto("");
			roomMapper.updateById(storageRoom);
			return R.ok(storageRoom, "修改成功");
		}
    }

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

		QueryWrapper<StorageCupboard> wrapper = new QueryWrapper<>();
		wrapper.eq("room_id",id);
		List<StorageCupboard> storageCupboards = cupboardMapper.selectList(wrapper);

		if (storageCupboards!=null){
			throw new RuntimeException(String.format("当前房间还存在柜子不允许删除"));
		}

        StorageRoom storageRoom = storageRoomService.getById(id);
		if(storageRoom.getRoomPhoto()!=null && storageRoom.getFileName()!=null){
			//删除图片
			ossFile.fileDelete("room" + "/" + storageRoom.getId() + "/" + storageRoom.getFileName());
		}

		if (storageRoomService.removeById(id)) {
			return R.ok(storageRoom, "对象删除成功");
		}
		else {
			return R.failed(storageRoom, "对象删除失败");
		}

    }

	/**
	 * 通过房间id和文件名获取图片"/getRoomPicture/{roomId}/{fileName}"
	 */
	@ApiOperation(value = "通过房间id和文件名获取图片", notes = "通过房间id和文件名获取图片")
	@GetMapping("/getRoomPicture/{roomId}/{fileName}" )
	//@PreAuthorize("@pms.hasPermission('imr_storage_room_get')" )
	public void getRoomPicture(@PathVariable("roomId") String roomId,
						@PathVariable("fileName") String fileName,
						HttpServletResponse httpServletResponse) throws Exception {
		StorageRoom storageRoom = roomMapper.selectById(roomId);
		if(storageRoom==null){
			throw new RuntimeException(String.format("当前房间数据不存在"));
		}
		ossFile.fileGet("room" + "/" + storageRoom.getId() + "/" + fileName, httpServletResponse.getOutputStream());
		httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(storageRoom.getFileName()));
	}



	/*
	@ApiOperation(value = "删除图片", notes = "删除图片")
	@SysLog("通过id删除" )
	@DeleteMapping("deleteRoom/{id}" )
	//@PreAuthorize("@pms.hasPermission('imr_storage_room_del')" )
	*/





	/**
	 * 列表
	 * @param
	 * @return
	 */
	@ApiOperation(value = "房间列表查询--下拉框的", notes = "房间列表查询--下拉框的")
	@GetMapping("/list" )
	//@PreAuthorize("@pms.hasPermission('imr_storage_room_get')" )
	public R<List<StorageRoom>> getStorageRoomList() {

		List<StorageRoom> storage = roomMapper.getStorageRoomList(Wrappers.<StorageRoom>query()
				.orderByDesc("sort")
		);
		return R.ok(storage,"查询成功");
	}





}
