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

namespace app\api\service\diy;

use think\Container;
use app\common\model\diy\LayoutPage as LayoutPageModel;

/**
 * @package app\api\service\diy
 * @class Layout
 * @author xzncit 2024-02-05
 */
class Layout {

    /**
     * @param $params
     * @return array
     */
    protected function getCondition($params){
        if(empty($params["id"])){
            $params["id"] = "home";
        }

        $condition = [];
        if(is_numeric($params["id"])){
            $condition[] = ["id","=",$params["id"]];
            $condition[] = ["page_type","=",2];
        }else{
            $condition[] = ["type","=",$params["id"]];
            $condition[] = ["page_type","=",1];
        }

        return $condition;
    }

    /**
     * 获取装修数据
     * @param array $params
     * @return array|void
     */
    public function getData($params=[]){
        $data         = ["name"=>"","list"=>[],"setting"=>[]];
        $result       = LayoutPageModel::where($this->getCondition($params))->find();
        $data["name"] = $result["name"]??"";
        if(!empty($result["setting"])){
            $setting = json_decode($result["setting"],true);
            if(!empty($setting)){
                $setting["type"] = 'archives';
                $globalSetting = $this->getWidget([$setting??[]]);
                if(is_array($globalSetting)){
                    $globalSetting = current($globalSetting);
                }

                $globalSetting["value"]["list"] = [];
                $data["setting"] = $globalSetting["value"];
            }
        }

        if(empty($result["content"])){
            return $data;
        }

        $array = json_decode($result["content"],true);
        if(empty($array)){
            return $data;
        }

        $data["list"] = $this->getWidget($array);
        return $data;
    }

    /**
     * 获取列表数据
     * @param array $params
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getList($params=[]){
        $result = LayoutPageModel::where($this->getCondition($params))->find();
        if(empty($result["setting"])){
            return [];
        }

        $setting = json_decode($result["setting"],true);
        if(empty($setting)){
            return [];
        }

        $setting["type"] = 'goods';
        $globalSetting = $this->getWidget([$setting??[]]);
        if(is_array($globalSetting)){
            $globalSetting = current($globalSetting);
        }

        $value = $globalSetting["value"];
        $list  = $value["list"]??[];
        $size  = $value["limit"]??10;

        $count = count($list);
        $start = ($params["page"] -1) * $size;
        $data  = array_slice($list,$start,$size);

        return [
            "total" => ceil($count / $size),
            "list"  => $data,
            "size"  => $size
        ];
    }

    /**
     * @param array $data
     * @return array
     */
    public function getWidget($data=[]){
        $array = [];
        foreach($data as $key=>$value){
            $obj = '\\app\\api\\service\\diy\\widget\\' . $this->getClassName($value["type"]);
            $array[$key]["type"]  = $value["type"];
            $array[$key]["value"] = $this->getInstance($obj,[],false)->getData($value["value"]);
        }

        return $array;
    }

    /**
     * 解析组件名称
     * @param $name
     * @return string
     */
    public function getClassName($name){
        $name = str_replace(["-","_"],"-",$name);
        $arr = explode("-",$name);
        $className = [];
        foreach($arr as $value){
            $className[] = ucfirst($value);
        }

        return implode("",$className);
    }

    /**
     * 创建类的实例 已经存在则直接获取
     * @access public
     * @param string $abstract    类名或者标识
     * @param array  $vars        变量
     * @param bool   $newInstance 是否每次创建新的实例
     * @return mixed
     */
    public function getInstance(string $abstract, array $vars = [], bool $newInstance = false){
        return Container::getInstance()->make($abstract, $vars, $newInstance);
    }

}