<?php
declare (strict_types = 1);

namespace app\index\controller;

use app\BaseController;
use app\index\model\LanguageModel;
use app\index\model\ProductCategoryModel;
use app\index\model\ProductModel;
use app\index\model\SysConfigModel;
use app\index\model\SysMallStoreEntranceModel;
use app\index\model\SysNavigationItemModel;
use think\facade\Lang;
use think\facade\View;

abstract class Common extends BaseController
{
    // 当前语言id
    protected $lang_id = 1;

    // 网站配置中的基本配置项
    protected $basic_config = [];

    /**
     * 控制器初始化
     * @access public
     */
    protected function initialize()
    {
        // 获取国家/语言列表
        $languages = $this->getLanguages();
        // 输出国家/语言列表
        View::assign('header_languages', $languages);

        // 获取当前语言
        $current_language = $this->getCurrentLanguage($languages);
        if (!empty($current_language)) {
            $this->lang_id = $current_language['id'];
        }

        // 获取产品分类
        $categorys = $this->getProductCategory($this->lang_id, true);
        // 输出产品分类
        View::assign('header_categorys', $categorys);

        // 获取热销产品
        $hot_products = $this->getHotProducts($this->lang_id);
        // 输出热销产品
        View::assign('header_hot_products', $hot_products);

        // 获取商品购买入口
        View::assign("header_mall_entrance", $this->getMallStoreEntrance($this->lang_id));

        // 输出顶部导航
        View::assign('header_navigation', $this->getNavigation('NAV_67f3701f3e831', $this->lang_id));

        // 获取系统配置
        $configs = $this->getSysConfig($this->lang_id, ['basic', 'contact', 'media']);
        $this->basic_config = $configs['basic'];
        // 输出系统配置
        View::assign('basic_config', $configs['basic']);
        View::assign('contact_config', $configs['contact']);
        View::assign('media_config', $configs['media']);

        // 获取底部导航
        $footer_navigation = $this->getNavigation('NAV_67f60be43df8d', $this->lang_id);
        // 输出底部导航
        View::assign('footer_navigation', $footer_navigation);
    }

    // 获取当前语言
    protected function getCurrentLanguage($languages)
    {
        $current_code = Lang::getLangSet();
        foreach ($languages as $item) {
            if ($item['lang_code'] == $current_code) {
                return $item;
            }
        }

        return [];
    }

    // 获取产品分类
    protected function getProductCategory($language = 1, $with_recommends = false)
    {
        $categorys = ProductCategoryModel::field([
                'id',
                'pid',
                'name',
                'icon',
                'level'
            ])
            ->when($with_recommends, function($query) {
                $query->with(['recommends' => function($query) {
                    $query->field(['id', 'category_id', 'title', 'image', 'desc', 'link'])->disabled(false)
                        ->order(['sort' => 'asc', 'id' => 'desc']);
                }]);
            })
            ->language($language)
            ->displayed()
            ->order(['sort' => 'asc', 'id' => 'desc'])
            ->select()
            ->hidden(["recommends.category_id"]);
        if ($categorys->isEmpty()) {
            return [];
        }

        return $this->toTreeAndChunk($categorys->toArray(), 0, 1);
    }
    private function toTreeAndChunk(array $categorys, int $pid, int|bool $level): array
    {
        $ret = [];
        foreach ($categorys as $item) {
            if ($item['pid'] == $pid) {
                $lv = $level;
                if ($level !== false) {
                    $item['level'] = $level;
                    $lv            = $level + 1;
                }
                $children = $this->toTreeAndChunk($categorys, $item['id'], $lv);
                if (!empty($children)) {
                    if ($lv == 1) {
                        $item['children'] = array_chunk($children, 2);
                    } else if ($lv == 2) {
                        $item['children'] = array_chunk($children, 3);
                    } else {
                        $item['children'] = $children;
                    }
                }
                $ret[] = $item;
            }
        }

        return $ret;
    }

    // 获取顶部导航
    protected function getNavigation($unique_label, $language = 1)
    {
        $nav = SysNavigationItemModel::hasWhere('navigation', [
                'unique_label' => $unique_label,
                'language_id'  =>  $language,
                'status'       => 1
            ])
            ->where('status', '=', 1)
            ->order(['sort' => 'asc', 'id' => 'asc'])
            ->select();
        if ($nav->isEmpty()) {
            return [];
        }

        return array_to_tree($nav->toArray(), 0, 'pid', 1, false);
    }

    // 获取热销产品
    protected function getHotProducts($language = 1, $limit = 3)
    {
        $products = ProductModel::field([
                'id',
                'name',
                'short_name',
                'cover_image',
            ])
            ->language($language)
            ->onSale(true)
            ->onShelves(true)
            ->hot(true)
            ->limit($limit)
            ->order(['sort' => 'asc', 'id' => 'desc'])
            ->select();
        if ($products->isEmpty()) {
            return [];
        }

        return $products->toArray();
    }

    // 获取国家/语言列表
    protected function getLanguages()
    {
        $languages = LanguageModel::alias('l')
            ->field([
                'l.id',
                'l.name'    => 'lang_name',
                'l.en_name' => 'lang_en_name',
                'l.code'    => 'lang_code',
                'l.icon'    => 'lang_icon',
                'l.url'     => 'lang_url',
                'c.id'      => 'country_id',
                'c.name'    => 'country_zh_name',
                'c.en_name' => 'country_en_name',
                'c.code'    => 'country_code',
            ])
            ->join('sys_country c', 'c.id = l.country_id')
            ->where('l.status', '=', 1)
            ->where('c.status', '=', 1)
            ->order(['l.sort' => 'asc', 'l.id' => 'asc'])
            ->select();

        return $languages;
    }

    // 获取商品购买入口
    private function getMallStoreEntrance($language = 1)
    {
        return SysMallStoreEntranceModel::field([
                'id',
                'name',
                'image',
                'hover_image',
                'link'
            ])
            ->language($language)
            ->enabled()
            ->order(['sort' => 'asc', 'id' => 'desc'])
            ->select()
            ?->each(function($item) {
                $item->image = thumb($item->image);
                return $item;
            });
    }

    // 获取系统联系方式配置
    protected function getSysConfig($language, $group = [])
    {
        $configs = SysConfigModel::alias('c')
            ->field([
                'c.id',
                'c.title',
                'c.name',
                'c.value',
                'c.extra',
                'c.type',
                'g.unique_label'
            ])
            ->join('sys_config_group g', 'g.id = c.group_id')
            ->where('g.unique_label', 'in', $group)
            ->where('g.language_id', '=', $language)
            ->order(['c.sort' => 'asc', 'c.id' => 'desc'])
            ->select();
        if ($configs->isEmpty()) {
            return [];
        }
        $configs = $configs->toArray();
        $data = [];
        foreach ($configs as $cfg) {
            $current = &$data;
            if (!isset($current[$cfg['unique_label']])) {
                $current[$cfg['unique_label']] = [];
            }
            $current = &$current[$cfg['unique_label']];

            // 根据name中"."拆分为多维数组
            $parts = explode('.', $cfg['name']);
            foreach ($parts as $part) {
                if (!isset($current[$part])) {
                    $current[$part] = [];
                }
                $current = &$current[$part];
            }
            $current = [
                'title' => $cfg['title'],
                'type'  => $cfg['type'],
                'value' => $cfg['value'],
                'extra' => $cfg['extra'],
            ];
        }
        unset($current);

        return $data;
    }
}
