package com.cku.oa.sys.service;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.Objects;

import javax.imageio.ImageIO;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ckfinder.connector.utils.FileUtils;
import com.cku.core.ZAErrorCode;
import com.cku.core.ZAException;
import com.cku.oa.dog.util.ImgCutUtil;
import com.cku.oa.sys.dao.FileDao;
import com.cku.oa.sys.entity.BaseFile;
import com.cku.thirdparty.oss.OssApiClient;
import com.cku.thirdparty.oss.OssUploadResult;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;

/**
 * 文件模块Service
 *
 * @author rain
 * @version 2015-12-18
 */
@Service
@Transactional(readOnly = false)
public class FileService extends CrudService<FileDao, BaseFile> {

	@Autowired
	private FileDao filedao;

	@Autowired
	private OssApiClient ossApiClient;

	public BaseFile get(String id) {
		return super.get(id);
	}

	public List<BaseFile> findList(BaseFile baseFile) {
		return super.findList(baseFile);
	}

	public Page<BaseFile> findPage(Page<BaseFile> page, BaseFile baseFile) {
		return super.findPage(page, baseFile);
	}

	@Transactional(readOnly = false)
	public void save(BaseFile baseFile) {
		super.save(baseFile);
	}

	@Transactional(readOnly = false)
	public void delete(BaseFile baseFile) {
		super.delete(baseFile);
	}

	public BaseFile uploadFile(MultipartFile multiFile, String module, String state) {
		// 上传实际的文件
		OssUploadResult uploadResult = ossApiClient.upload(multiFile, module);
		return createBaseFile(multiFile, uploadResult.getObjectName(), uploadResult.getExtensionPath(), state);
	}

	public BaseFile watermarkImg(MultipartFile multiFile, String module, String state, String type) {
		// 上传实际的文件
		String fileDir = watermark(multiFile, type);
		OssUploadResult uploadResult = ossApiClient.upload(fileDir, module, Boolean.TRUE);
		return createBaseFile(multiFile, uploadResult.getObjectName(), uploadResult.getExtensionPath(), state);
	}

	private BaseFile createBaseFile(MultipartFile multiFile, String fileName, String extensionPath, String state) {
		// 插入一条数据库记录
		BaseFile baseFile = new BaseFile();
		baseFile.setName(fileName);
		baseFile.setOrginalname(multiFile.getOriginalFilename());
		baseFile.setType(multiFile.getContentType());
		if ("image/beauty/jpeg".equals(multiFile.getContentType())) {
			baseFile.setType("image/jpeg");
		}
		baseFile.setExtension(FileUtils.getFileExtension(multiFile.getOriginalFilename()));
		baseFile.setSize(multiFile.getSize());
		baseFile.setLocation(extensionPath);
		// 磁盘和OSS过度期间，此处填充 区分标识，以便获取时拼接地址
		baseFile.setDescription(OssApiClient.ALI_OSS);
		baseFile.setOwnerid(UserUtils.getUser().getId());
		baseFile.setOwnername(UserUtils.getUser().getName());
		baseFile.setStatus("0");
		baseFile.setOpenFlag(state);
		super.save(baseFile);
		return baseFile;
	}

	public final static String watermark(MultipartFile multiFile, String type) {
		String fileDir = null;
		FileOutputStream out = null;
		try {
			// 目标文件
			Image src = ImageIO.read(multiFile.getInputStream());
			int wideth = src.getWidth(null);
			int height = src.getHeight(null);
			BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, wideth, height, null);
			String fileName = "watermark.png";
			if ("1".equals(type)) {
				fileName = "watermark1.png";
			}
			// 水印文件
			Image src_biao = ImageIO.read(new FileInputStream(FileService.class.getResource("/").getPath() + fileName));
			int wideth_biao = src_biao.getWidth(null);
			int height_biao = src_biao.getHeight(null);
			int y = 260;
			if ("1".equals(type)) {
				y = (height - height_biao) / 2;
			}
			g.drawImage(src_biao, wideth - wideth_biao, y, wideth_biao, height_biao, null);
			// 水印文件结束
			g.dispose();
			fileDir = System.getProperty("java.io.tmpdir") + File.separator + multiFile.getOriginalFilename();
			out = new FileOutputStream(new File(fileDir));
			ImageIO.write(image, "jpg", out);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(out);
		}
		return fileDir;
	}

	public void deleteFile(BaseFile baseFile) {
		File file = new File(baseFile.getLocation());
		file.delete(); // 删除文件
		filedao.delete(baseFile);// 删除文件记录
	}

	public void fileCut(String fileId) {
		BaseFile baseFile = this.get(fileId);
		if (Objects.isNull(baseFile)) {
			throw new ZAException(ZAErrorCode.ZA_ERROR, "文件ID错误");
		}
		if (OssApiClient.ALI_OSS.equals(baseFile.getDescription())) {
			String newFileDir = System.getProperty("java.io.tmpdir") + File.separator + baseFile.getName();
			ossApiClient.fileDownload(baseFile.getLocation(), baseFile.getName(), newFileDir);
			ImgCutUtil.cut(815, 310, 630, 630, newFileDir, newFileDir);
			ossApiClient.upload(newFileDir, baseFile.getLocation(), Boolean.TRUE);
		} else {
			String newFileDir = Global.getConfig("file.dir") + File.separator + baseFile.getLocation() + File.separator
					+ baseFile.getName();
			ImgCutUtil.cut(815, 310, 630, 630, newFileDir, newFileDir);
		}
	}

	public void fileDownload(String fileId, OutputStream out) {
		BaseFile baseFile = this.get(fileId);
		this.fileDownload(baseFile, out);
	}

	public void fileDownload(BaseFile baseFile, OutputStream out) {
		if (Objects.isNull(baseFile)) {
			throw new ZAException(ZAErrorCode.ZA_ERROR, "文件ID错误");
		}
		if (OssApiClient.ALI_OSS.equals(baseFile.getDescription())) {
			ossApiClient.fileDownload(baseFile.getLocation(), baseFile.getName(), out);
		} else {
			FileInputStream fis = null;
			try {
				fis = new FileInputStream(Global.getConfig("file.dir") + File.separator + baseFile.getLocation()
						+ File.separator + baseFile.getName());
				int read;
				byte b[] = new byte[1024 * 1024];
				read = fis.read(b);
				while (read != -1) {
					out.write(b, 0, read);
					read = fis.read(b);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (Objects.nonNull(fis)) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	// 查多个
	public List<BaseFile> getByIds(List<String> ids) {
		return dao.getByIds(ids);
	}

	
	public void createFile(String path) throws IOException {
		File file = new File(path);
		if (!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		//file.createNewFile();
	}
}