<?php
// +----------------------------------------------------------------------
// | A3Mall
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: xzncit <158373108@qq.com>
// +----------------------------------------------------------------------

namespace app\common\library\file;

use think\facade\Filesystem;
use think\facade\Request;
use think\Image;
use think\facade\Config;
use think\exception\ValidateException;
use app\common\exception\BaseException;
use app\common\model\Attachment as AttachmentModel;

/**
 * 文件管理类
 * @package app\common\library\file
 * @class FileManager
 * @author xzncit 2023-09-02
 */
class FileManager {

    /**
     * 上传附件
     * @param string $name
     * @param int $catID
     * @param false $thumb
     * @param array $option
     * @return array
     * @throws BaseException
     */
    public static function upload($name="",$catID=0,$thumb=false,$option=[]){
         try{
            $options = array_merge([
                "disk"      => "public",
                "ext"       => ["jpg","jpeg","png","gif","bmp"],
                "original"  => false,
                "save"      => true
            ],$option);

            $upload = Request::file($name);
            validate([
                "file"=>[
                    "fileSize"  => File::to('bytes'),
                    "fileExt"   => is_string($options["ext"]) ? [$options["ext"]] : $options["ext"]
                ]
            ],[
                "file"=>[
                    "fileSize"  => "您上传的文件过大",
                    "fileExt"   => "您选择的文件不允许上传"
                ]
            ])->check(["file"=>$upload]);

            $dir   = self::getUploadPath($options["disk"]);
            $path  = $options["disk"] == "root" ? "" : self::getDirectory($upload->extension());
            if(!$options["original"]){
                $uploadFile = Filesystem::disk($options["disk"])->putFile($path, $upload);
            }else{
                $uploadFile = Filesystem::disk($options["disk"])->putFileAs($path, $upload,$upload->getOriginalName());
            }

            $name         = basename($uploadFile);
            $filePath     = str_replace('\\','/',$dir . '/' . $uploadFile);

            // 如果是证书文件，将不上传到oss存储服务器上
            $oss = ["storage"=>"local","path"=>$filePath];
            if(!in_array($upload->extension(),["pem","crt"])){
                // $ossInfo = OSS::create()->upload($filePath);
            }

            $mime = $width = $height = '';
            if(in_array($upload->extension(),["jpg","jpeg","png","gif","bmp"])){
                $image  = Image::open($filePath);
                $mime   = $image->mime();
                $width  = $image->width();
                $height = $image->height();
            }

            $array = [
                "cat_id"         => $catID,
                "user_id"        => 0,
                "filename"       => $upload->getOriginalName(),
                "path"           => "/".$filePath,
                "mimetype"       => $mime,
                "image_width"    => $width,
                "image_height"   => $height,
                "image_type"     => strtolower($upload->extension()),
                "filesize"       => $upload->getSize(),
                "storage"        => $oss["storage"],
                "sha1"           => $upload->hash(),
                "create_time"    => time(),
                "update_time"    => time()
            ];

            $array["id"] = $options["save"] ? AttachmentModel::create($array)->id : 0;
            if(!$thumb || !in_array($upload->extension(),["jpg","jpeg","png","gif","bmp"])){
                return $array;
            }

            $thumbImage = Config::get("website.thumb_image",[]);
            foreach($thumbImage as $key=>$val){
                $image = Image::open($filePath);
                $tempPath = str_replace($name, $key . '_' . $name, $filePath);
                $image->thumb($val[0], $val[1])->save($tempPath);
                // OSS::create()->upload($tempPath);
            }

            return $array;
        }catch (ValidateException $ex){
            throw new BaseException($ex->getError(),$ex->getCode());
        }catch (\Exception $ex){
            throw new BaseException($ex->getMessage(),$ex->getCode());
        }
    }

    /**
     * 获取上传目录
     * @param $disk
     * @return string
     */
    public static function getUploadPath($disk){
        switch($disk){
            case "root":
                return "";
            case "certificate":
                return "runtime/certificate";
            case "public":
            default:
                return "uploads";
        }
    }

    /**
     * 获取文件分类目录
     * @param $suffix
     * @return string
     */
    public static function getDirectory($suffix){
        if(in_array($suffix,["jpg","png","gif","jpeg","bmp"])){
            return "images";
        }else if(in_array($suffix,["mp4"])){
            return "video";
        }else if(in_array($suffix,["zip","rar","txt","apk","wgt","csv","xls","xlsx"])){
            return "file";
        }else if(in_array($suffix,["pem"])){
            return "";
        }
    }

    /**
     * 删除附件文件
     * @param array $data
     * @return bool
     * @throws BaseException
     */
    public static function delete($data=[]){
        if(empty($data["path"])){
            throw new BaseException("附件不存在",0);
        }

        $path       = trim($data["path"],"/");
        $thumbImage = Config::get("website.thumb_image",[]);
        $arr        = explode("/",$path);
        $lastImage  = end($arr);
        file_exists($path) && unlink($path);
        AttachmentModel::where(["path"=>$data["path"]])->delete();
        foreach($thumbImage as $key=>$val){
            $thumb = str_replace($lastImage, $key . '_' . $lastImage, $path);
            file_exists($thumb) && unlink($thumb);
        }

        return true;
    }

}