<?php

namespace app\controller;

use Exception;
use Intervention\Image\ImageManagerStatic as Image;
use plugin\admin\app\controller\Crud;
use plugin\admin\app\model\Upload;

use support\Db;
use support\exception\BusinessException;
use support\Request;
use support\Response;
use hg\apidoc\annotation as Apidoc;

#[Apidoc\Title("上传")]
#[Apidoc\Group("Upload")]
#[Apidoc\Sort(1)]
class UploadController extends Crud
{
    /**
     * @var Upload
     */
    protected $model = null;

    /**
     * 只返回当前管理员数据
     * @var string
     */
    protected $dataLimit = 'personal';

    /**
     * 构造函数
     * @return void
     */
    public function __construct()
    {
        $this->model = new Upload;
    }

    #[Apidoc\Title("上传")]
    #[Apidoc\Url("api/file_front.html")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("file", type: "file", require: true, desc: "上传图片")]
    #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
    #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
    public function file_front(Request $request): Response
    {
        $data     = $this->base($request, '/upload/img/' . date('Ymd'));
        $realpath = $data['realpath'];
        try {
            $img        = Image::make($realpath);
            $max_height = 1170;
            $max_width  = 1170;
            $width      = $img->width();
            $height     = $img->height();
            $ratio      = 1;
            if ($height > $max_height || $width > $max_width) {
                $ratio = $width > $height ? $max_width / $width : $max_height / $height;
            }
            $img->resize($width * $ratio, $height * $ratio)->save($realpath);

        } catch (Exception $e) {
            unlink($realpath);
            return error('处理图片发生错误');
        }
         Db::table('wa_users')->where('id',$request->user_data['id'])->update(['front_ima'=>$data['url']]);
        return success([
            'url'  => imageToBase64($data['url']),
            'path' => $data['url'],
        ]);
    }

    #[Apidoc\Title("上传")]
    #[Apidoc\Url("api/file_reverse.html")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("file", type: "file", require: true, desc: "上传图片")]
    #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
    #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
    public function file_reverse(Request $request): Response
    {
        $data     = $this->base($request, '/upload/img/' . date('Ymd'));
        $realpath = $data['realpath'];
        try {
            $img        = Image::make($realpath);
            $max_height = 1170;
            $max_width  = 1170;
            $width      = $img->width();
            $height     = $img->height();
            $ratio      = 1;
            if ($height > $max_height || $width > $max_width) {
                $ratio = $width > $height ? $max_width / $width : $max_height / $height;
            }
            $img->resize($width * $ratio, $height * $ratio)->save($realpath);

        } catch (Exception $e) {
            unlink($realpath);
            return error('处理图片发生错误');
        }
        Db::table('wa_users')->where('id',$request->user_data['id'])->update(['reverse_ima'=>$data['url']]);
        return success([
            'url'  => imageToBase64($data['url']),
            'path' => $data['url'],
        ]);
    }


    /**
     * 获取上传数据
     * @param Request $request
     * @param $relative_dir
     * @return array
     * @throws BusinessException|RandomException
     */
    protected function base(Request $request, $relative_dir): array
    {
        $relative_dir = ltrim($relative_dir, '\\/');
        $file         = current($request->file());
        if (!$file || !$file->isValid()) {
            throw new BusinessException('未找到上传文件', 400);
        }

        $admin_public_path = rtrim(config('app.public_path', ''), '\\/');
        $base_dir          = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
        $full_dir          = $base_dir . $relative_dir;
        if (!is_dir($full_dir)) {
            mkdir($full_dir, 0777, true);
        }

        $ext       = $file->getUploadExtension() ?: null;
        $mime_type = $file->getUploadMimeType();
        $file_name = $file->getUploadName();
        $file_size = $file->getSize();

        if (!$ext && $file_name === 'blob') {
            [$___image, $ext] = explode('/', $mime_type);
            unset($___image);
        }

        $ext               = strtolower($ext);
        $ext_forbidden_map = ['php', 'php3', 'php5', 'css', 'js', 'html', 'htm', 'asp', 'jsp'];
        if (in_array($ext, $ext_forbidden_map)) {
            throw new BusinessException('不支持该格式的文件上传', 400);
        }

        $relative_path = $relative_dir . '/' . bin2hex(pack('Nn', time(), random_int(1, 65535))) . ".$ext";
        $full_path     = $base_dir . $relative_path;
        $file->move($full_path);
        $image_with = $image_height = 0;
        if ($img_info = getimagesize($full_path)) {
            [$image_with, $image_height] = $img_info;
            $mime_type = $img_info['mime'];
        }
        return [
            'url'          => "/$relative_path",
            'name'         => $file_name,
            'realpath'     => $full_path,
            'size'         => $file_size,
            'mime_type'    => $mime_type,
            'image_with'   => $image_with,
            'image_height' => $image_height,
            'ext'          => $ext,
        ];
    }

    #[Apidoc\Title("上传图片base64")]
    #[Apidoc\Url("api/base_file.html")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("baseimg", type: "string", require: true, desc: "base64编码")]
    #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
    #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
    public function base_file(Request $request): Response
    {
        $param = $request->all();
        try {
            $base64Image_one = $param['baseimg'];                                                                                           // 获取Base64字符串
            $imageData       = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image_one));                             // 移除数据URL的前缀并解码
            $imageName       = $request->user_data['id'] . time() . '.png';                                                             // 生成一个唯一的文件名

            $data              = '/upload/img/' . date('Ymd');
            $relative_dir      = ltrim($data, '\\/');
            $admin_public_path = rtrim(config('app.public_path', ''), '\\/');
            $base_dir          = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
            $full_dir          = $base_dir . $relative_dir;
            if (!is_dir($full_dir)) {
                mkdir($full_dir, 0777, true);
            }
            $imagePath_one = '/upload/img/' . date('Ymd') . '/' . $imageName; // 指定保存路径和文件名

            // 保存图片到服务器
            file_put_contents($base_dir . $imagePath_one, $imageData);
        } catch (Exception $e) {
            return error('处理图片发生错误');
        }
        Db::table('wa_users')->where('id', $request->user_data['id'])->update(['sign_img' => $imagePath_one]);
        return adminsuccess([
            'url'  => imageToBase64($imagePath_one),
            'path' => $imagePath_one,
        ]);
    }

    #[Apidoc\Title("上传图片base64")]
    #[Apidoc\Url("api/card_file.html")]
    #[Apidoc\Method("POST")]
    #[Apidoc\Param("baseimg", type: "string", require: true, desc: "base64编码")]
    #[Apidoc\Header("token", type: "string", require: true, desc: "身份令牌Token", mock: "@token")]
    #[Apidoc\Header("front_ima", type: "string", require: true, desc: "正面图片——base64", mock: "")]
    #[Apidoc\Header("reverse_ima", type: "string", require: true, desc: "反面图片——base64", mock: "@")]
    #[Apidoc\Returned(name: "url", type: "string", require: true, desc: '前端展示地址', default: '12317309127904')]
    public function card_file(Request $request): Response
    {
        $param = $request->all();
        try {

            if (!empty($param['front_ima'])) {
                $base64Image_one = $param['front_ima'];                                                                                           // 获取Base64字符串
                $imageData       = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image_one));                             // 移除数据URL的前缀并解码
                $imageName       = $request->user_data['id'] . '1' . time() . '.png';                                                             // 生成一个唯一的文件名

                $data              = '/upload/img/' . date('Ymd');
                $relative_dir      = ltrim($data, '\\/');
                $admin_public_path = rtrim(config('app.public_path', ''), '\\/');
                $base_dir          = $admin_public_path ? $admin_public_path . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
                $full_dir          = $base_dir . $relative_dir;
                if (!is_dir($full_dir)) {
                    mkdir($full_dir, 0777, true);
                }
                $imagePath_one = '/upload/img/' . date('Ymd') . '/' . $imageName; // 指定保存路径和文件名
                // 保存图片到服务器
                file_put_contents($base_dir . $imagePath_one, $imageData);
            } else {
                $imagePath_one = $request->user_data['front_ima'];
            }
            if (!empty($param['reverse_ima'])) {
                $base64Image_two = $param['reverse_ima'];                                                                                           // 获取Base64字符串
                $imageData_two   = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $base64Image_two));                             // 移除数据URL的前缀并解码
                $imageName_two   = $request->user_data['id'] . '2' . time() . '.png';                                                             // 生成一个唯一的文件名

                $data                  = '/upload/img/' . date('Ymd');
                $relative_dir_two      = ltrim($data, '\\/');
                $admin_public_path_two = rtrim(config('app.public_path', ''), '\\/');
                $base_dir_two          = $admin_public_path_two ? $admin_public_path_two . DIRECTORY_SEPARATOR : base_path() . '/plugin/admin/public/';
                $full_dir_two          = $base_dir_two . $relative_dir_two;
                if (!is_dir($full_dir_two)) {
                    mkdir($full_dir_two, 0777, true);
                }
                $imagePath_two = '/upload/img/' . date('Ymd') . '/' . $imageName_two; // 指定保存路径和文件名
                // 保存图片到服务器
                file_put_contents($base_dir_two . $imagePath_two, $imageData_two);
            } else {
                $imagePath_two = $request->user_data['reverse_ima'];
            }


        } catch (Exception $e) {
            return error('处理图片发生错误');
        }
        Db::table('wa_users')->where('id', $request->user_data['id'])
            ->update([
                'front_ima'   => $imagePath_one,
                'reverse_ima' => $imagePath_two,
            ]);
        return adminsuccess([
            'front_ima'   => imageToBase64($imagePath_one),
            'reverse_ima' => imageToBase64($imagePath_two),
            'path'        => $imagePath_one,
        ]);
    }

}
