<?php

namespace app\common\exception;

use think\helper\Arr;
use app\common\arw\adjfut\src\Exception\ErrorMsg;

class Base64
{
    /**
     * 类型
     *
     * @var string
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    private $type = '';
    /**
     * base64内容
     *
     * @var string
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    private $body = '';
    /**
     * base64
     *
     * @var string
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    private $base64 = '';
    /**
     * 文件后缀映射
     */
    private const FILE_EXT_MAP = [
        'text/html' => 'html',
        'text/css' => 'css',
        'text/javascript' => 'js',
        'image/gif' => 'gif',
        'image/png' => 'png',
        'image/jpeg' => 'jpg',
        'image/x-icon' => 'ico',
    ];
    /**
     * 实例化
     *
     * @param string $base64
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    public function __construct(string $base64)
    {
        $parse = self::parse($base64);
        $this->base64 = $base64;
        $this->type = $parse['type'];
        $this->body = $parse['body'];
    }

    /**
     * 获取文件后缀
     *
     * @return string
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    public function getFileExt(): string
    {
        return Arr::get(self::FILE_EXT_MAP, $this->type, '');
    }

    /**
     * 判断是否是base64图片字符串
     *
     * @return boolean
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    public function isImage(): bool
    {
        return in_array($this->type, [
            'image/gif',
            'image/png',
            'image/jpeg',
            'image/x-icon',
        ]);
    }

    /**
     * 保存base64图片
     *
     * @param string $path
     * @return void
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    public function saveImage(string $path): void
    {
        file_put_contents($path, base64_decode($this->body));
    }

    /**
     * 判断是否是base64图片字符串
     *
     * @param string $base64
     * @return boolean
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    public static function isBase64Image(string $base64): bool
    {
        $ins = new self($base64);
        return $ins->isImage();
    }

    /**
     * 保存base64图片
     *
     * @param string $base64
     * @param string $path
     * @return void
     */
    public static function saveBase64Image(string $base64, string $path): void
    {
        $ins = new self($base64);
        $ins->saveImage($path);
    }

    /**
     * 解析base64
     *
     * @param string $base64
     * @return array
     * @date 2023-01-09
     * @example
     * @author arw
     * @since 1.0.0
     */
    private static function parse(string $base64): array
    {
        $prefix = 'data:';
        $validate = substr($base64, 0, strlen($prefix)) === $prefix;
        if (!$validate) {
            throw new ErrorMsg("非法base64 开头data:", 1);
        }
        $explode = explode(';base64,', $base64);
        if (count($explode) != 2) {
            throw new ErrorMsg("非法base64 不存在;base64,", 1);
        }
        list($type, $body) = $explode;
        $type = str_replace('data:', '', $type);
        return [
            'type' => $type,
            'body' => $body
        ];
    }
}
