package com.sy.coinage.file.controller;

import java.io.File;
import java.util.Date;
import javax.validation.Valid;

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.sy.coinage.config.CustomConfig;
import com.sy.coinage.core.annotation.CurrentUser;
import com.sy.coinage.core.aop.annotation.Operation;
import com.sy.coinage.core.interceptor.Update;
import com.sy.coinage.core.req.IdReq;
import com.sy.coinage.core.util.DateUtils;
import com.sy.coinage.core.vo.CacheUserVO;
import com.sy.coinage.file.model.MyFile;
import com.sy.coinage.file.req.MyFileListReq;
import com.sy.coinage.file.req.MyFileReq;
import com.sy.coinage.file.service.IMyFileService;
import com.sy.coinage.sys.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
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;

/**
 * MyFileController
 */
@RestController
@RequestMapping(value = "/file")
public class MyFileController {

    @Autowired
    private IMyFileService myFileService;

    @Autowired
    private CustomConfig customConfig;

    @Autowired
    private IUserService userService;

    /**
     * 获取单条记录
     *
     * @param req {@link IdReq}
     * @return MyFile
     */
    @PostMapping("/get")
    public Object get(@RequestBody @Valid IdReq req) {
        MyFile data = this.myFileService.getById(req.getId());
        return data;
    }

    /**
     * list(带分页列表)
     *
     * @param req {@link MyFileListReq}
     * @return PageInfo<MyFile>
     */
    @PostMapping(value = "/list")
    public IPage<MyFile> list(@RequestBody MyFileListReq req) {
        LambdaQueryWrapper<MyFile> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(req.getName()), MyFile::getName, req.getName());
        queryWrapper.orderByDesc(MyFile::getId);
        Page<MyFile> page = new Page<>(req.getPage(), req.getRows());
        IPage<MyFile> data = this.myFileService.page(page, queryWrapper);
        return data;
    }

    /**
     * 修改
     *
     * @param req req {@link MyFileReq}
     * @return null
     */
    @PostMapping("/update")
    @Operation(value = "修改文件")
    public Object update(@RequestBody @Validated({Update.class}) MyFileReq req,
                         @CurrentUser CacheUserVO user) {
        MyFile model = this.myFileService.getById(req.getId());
        if (model != null) {
            BeanUtils.copyProperties(req, model);
            model.setUpdateTime(new Date());
            this.myFileService.updateById(model);
        }
        return "";
    }

    /**
     * 删除
     *
     * @param req {@link IdReq}
     * @return null
     */
    @PostMapping("/delete")
    @Operation(value = "删除文件")
    public Object delete(@RequestBody @Valid IdReq req) {
        MyFile model = this.myFileService.getById(req.getId());
        String filePath = customConfig.getAttaPath() + model.getUrl();
        File f = new File(filePath);
        if (f.exists()) {
            f.delete();
        }
        this.myFileService.removeById(req.getId());
        return "";
    }


    @PostMapping("/imp")
    public Object imp(@RequestParam(required = true) MultipartFile file,
                      Integer id,
                      @CurrentUser CacheUserVO user) throws Exception {
        String saveUrl = this.imp(file);
        String fname = file.getOriginalFilename();
        String fileSize = this.convertFileSize(file.getSize());
        MyFile model = null;
        if (id != null && id > 0) {
            model = this.myFileService.getById(id);
            String filePath = customConfig.getAttaPath() + model.getUrl();
            File f = new File(filePath);
            if (f.exists()) {
                f.delete();
            }
            model.setCreateTime(new Date());
            model.setName(fname);
            model.setUrl(saveUrl);
            model.setCreateBy(user.getRealName());
            model.setUpdateTime(model.getCreateTime());
            model.setFileSize(fileSize);
            this.myFileService.updateById(model);
        } else {
            model = new MyFile();
            model.setCreateTime(new Date());
            model.setName(fname);
            model.setUrl(saveUrl);
            model.setCreateBy(user.getRealName());
            model.setUpdateTime(model.getCreateTime());
            model.setFileSize(fileSize);
            this.myFileService.save(model);
        }
        return "";
    }

    private String imp(MultipartFile file) throws Exception {
        String date = DateUtils.toString(new Date(), DateUtils.YYMMDD);
        // 上传文件的名称
        String fname = file.getOriginalFilename();
        // 获取后缀
        String sufferFix = fname.substring(fname.lastIndexOf("."));
        // 访问url
        String fileUrl = customConfig.getPathUrl() + "/" + date;
        // 存储路径
        String filePath = customConfig.getAttaPath() + fileUrl;
        File path = new File(filePath);
        if (!path.exists()) {
            path.mkdirs();
        }
        long s = System.currentTimeMillis();
        // 文件访问url
        String saveUrl = fileUrl + "/" + s + sufferFix;
        // 文件存储路径
        String savePath = filePath + "/" + s + sufferFix;
        File dest = new File(savePath);
        // 生成临时文件
        file.transferTo(dest.getAbsoluteFile());
        return saveUrl;
    }

    /**
     * -字节转换
     *
     * @param size 字节大小
     * @return 转换后值
     */
    public String convertFileSize(long size) {
        long kb = 1024;
        long mb = kb * 1024;
        long gb = mb * 1024;
        if (size >= gb) {
            return String.format("%.1f GB", (float) size / gb);
        } else if (size >= mb) {
            float f = (float) size / mb;
            return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
        } else if (size >= kb) {
            float f = (float) size / kb;
            return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
        } else {
            return String.format("%d B", size);
        }
    }

}
