<?php
declare (strict_types = 1);

namespace app\admin\controller\v1;

use app\admin\model\v1\SysImageUploadRecordModel;
use app\admin\model\v1\SysVideoUploadRecordModel;
use app\admin\model\v1\SysAttachmentUploadRecordModel;
use Intervention\Image\ImageManager;
use think\facade\Filesystem;

/**
 * 文件上传控制器
 */
class Upload
{
    // 上传图片
    public function image()
    {
        $param = request()->param(['module' => 'unknown']);
        if (is_null($param)) {
            return error('请确定请求参数正确');
        }
        $file = request()->file('image');
        if (is_null($file)) {
            return error('请确定上传对象或字段是否正确');
        }

        try {
            $max_size = strtobytes(env('ADMIN_API.MAX_IMAGE_SIZE', '1mb'));
            $validate = validate([
                'module' => 'require|max:64',
                'image'  => "fileSize:$max_size|fileExt:jpg,jpeg,png,gif"
            ]);
            if (!$validate->check(['module' => $param['module'], 'image' => $file])) {
                return error($validate->getError());
            }

            $storage = config('filesystem.disks.image.url');

            $filemd5  = $file->md5();
            $filesha1 = $file->sha1();

            $image_model = SysImageUploadRecordModel::md5($filemd5)->find();
            if (is_null($image_model)) {
                $filename = Filesystem::disk('image')->putFile($param['module'], $file);
                // 生成缩略图
                $image_manager = new ImageManager(new \Intervention\Image\Drivers\Gd\Driver());
                $image = $image_manager->read('.' . $storage . '/' . $filename);
                $image->scale(200, 200);
                $idx = strrpos($filename, '.');
                $thumb_filename = mb_substr($filename, 0, $idx) . '_thumb.' . mb_substr($filename, $idx + 1);
                $image->save('.' . $storage . '/' . $thumb_filename);

                // 保存图片
                $image_model              = new SysImageUploadRecordModel();
                $image_model->language_id = request()->lang_id;
                $image_model->module      = $param['module'];
                $image_model->image_path  = $filename;
                $image_model->image_thumb = $thumb_filename;
                $image_model->file_size   = $file->getSize();
                $image_model->file_type   = $file->getOriginalMime();
                $image_model->file_md5    = $filemd5;
                $image_model->file_sha1   = $filesha1;
                if (!$image_model->save()) {
                    return error('上传失败');
                }
            }

            return success('操作成功', [
                'path'       => $storage . '/' . $image_model->image_path,
                'thumb_path' => $storage . '/' . $image_model->image_thumb,
                'filemd5'    => $image_model->file_md5,
                'filesha1'   => $image_model->file_sha1
            ]);
        } catch (\Throwable $th) {
            return error($th->getMessage());
        }

        return error('上传失败');
    }

    /**
     * 上传视频
     */
    public function video()
    {
        $param = request()->param(['module' => 'unknown']);
        if (is_null($param)) {
            return error('请确定请求参数正确');
        }
        $file = request()->file('video');
        if (is_null($file)) {
            return error('请确定上传对象或字段是否正确');
        }

        try {
            $max_size = strtobytes(env('ADMIN_API.MAX_VIDEO_SIZE', '100mb'));
            $validate = validate([
                'module' => 'require|max:64',
                'video'  => "fileSize:$max_size|fileExt:mp4"
            ]);
            if (!$validate->check(['module' => $param['module'], 'video' => $file])) {
                return error($validate->getError());
            }

            $storage = config('filesystem.disks.video.url');

            $filemd5  = $file->md5();
            $filesha1 = $file->sha1();

            $video = SysVideoUploadRecordModel::md5($filemd5)->find();
            if (is_null($video)) {
                $filename = Filesystem::disk('video')->putFile($param['module'], $file);

                // 保存视频
                $video              = new SysVideoUploadRecordModel();
                $video->language_id = request()->lang_id;
                $video->module      = $param['module'];
                $video->video_path  = $filename;
                $video->file_size   = $file->getSize();
                $video->file_type   = $file->getOriginalMime();
                $video->file_md5    = $filemd5;
                $video->file_sha1   = $filesha1;
                if (!$video->save()) {
                    return error('上传失败');
                }
            }

            return success('上传成功', [
                'path'      => $storage . '/' . $video->video_path,
                'file_md5'  => $video->file_md5,
                'file_sha1' => $video->file_sha1
            ]);
        } catch (\Throwable $th) {
            return error($th->getMessage());
        }

        return error('上传失败');
    }

    /**
     * 附件上传
     */
    public function attachment()
    {
        $file = request()->file('attachment');
        if (is_null($file)) {
            return error('请确定上传对象或字段是否正确');
        }

        try {
            $max_size = strtobytes(env('ADMIN_API.MAX_ATTACHMENT_SIZE', '100mb'));
            $validate = validate([
                'attachment'  => "fileSize:$max_size|fileExt:zip,rar,7z,doc,docx,xls,xlsx,csv,ppt,pptx,pdf,txt"
            ]);
            if (!$validate->check(['attachment' => $file])) {
                return error($validate->getError());
            }

            $filemd5  = $file->md5();
            $filesha1 = $file->sha1();

            $attachment = SysAttachmentUploadRecordModel::md5($filemd5)->find();
            if (is_null($attachment)) {
                $filename = Filesystem::disk('public')->putFile('attachments', $file);

                // 保存视频
                $attachment                  = new SysAttachmentUploadRecordModel();
                $attachment->language_id     = request()->lang_id;
                $attachment->attachment_path = $filename;
                $attachment->file_size       = $file->getSize();
                $attachment->file_type       = $file->getOriginalMime();
                $attachment->file_md5        = $filemd5;
                $attachment->file_sha1       = $filesha1;
                if (!$attachment->save()) {
                    return error('上传失败');
                }
            }

            $storage = config('filesystem.disks.public.url');
            return success('上传成功', [
                'path'      => $storage . '/' . $attachment->attachment_path,
                'file_md5'  => $attachment->file_md5,
                'file_sha1' => $attachment->file_sha1
            ]);
        } catch (\Throwable $th) {
            return error($th->getMessage());
        }

        return error('上传失败');
    }
}
