<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\validate\domain;


/**
 * 渠道领域验证器
 * @package app\validate\domain
 */
class ChannelDomainValidator implements DomainValidatorInterface
{
    private const LINK_TYPES = ['internal', 'mini_program', 'external'];
    private const DISPLAY_TYPES = ['icon_text', 'icon', 'text'];


    /**
     * 校验渠道数据
     * @param array $data
     * @param string $scene
     * @return array
     */
    public function validate(array $data, string $scene = ''): array
    {
        $errors = match ($scene) {
            'save_bottom_nav' => $this->validateSaveBottomNav($data),
            default => [],
        };

        return ['ok' => empty($errors), 'errors' => $errors];
    }


    /**
     * 校验保存底部导航数据
     * @param array $data
     * @return array 错误信息数组
     */
    private function validateSaveBottomNav(array $data): array
    {
        $errors = [];
        $payload = $data['data'] ?? null;
        if (!is_array($payload)) {
            return ['data' => ''];
        }

        $links = is_array($payload['links'] ?? null) ? $payload['links'] : null;
        $menus = is_array($payload['menus'] ?? null) ? $payload['menus'] : null;
        if ($links === null || $menus === null) {
            return ['data' => ''];
        }

        $linkIds = [];
        foreach ($links as $index => $link) {
            if (!is_array($link)) {
                $errors['links.' . $index] = '';
                continue;
            }

            $name = trim((string)($link['name'] ?? ''));
            $type = trim((string)($link['type'] ?? ''));
            if ($name === '') {
                $errors['links.' . $index . '.name'] = '';
            }
            if (!in_array($type, self::LINK_TYPES, true)) {
                $errors['links.' . $index . '.type'] = '';
                continue;
            }

            if ($type === 'internal' && trim((string)($link['path'] ?? '')) === '') {
                $errors['links.' . $index . '.path'] = '';
            }
            if ($type === 'mini_program' && trim((string)($link['app_id'] ?? '')) === '') {
                $errors['links.' . $index . '.app_id'] = '';
            }
            if ($type === 'mini_program' && trim((string)($link['page_path'] ?? '')) === '') {
                $errors['links.' . $index . '.page_path'] = '';
            }
            if ($type === 'external' && trim((string)($link['url'] ?? '')) === '') {
                $errors['links.' . $index . '.url'] = '';
            }

            $id = (int)($link['id'] ?? 0);
            if ($id > 0) {
                $linkIds[] = $id;
            }
        }

        foreach ($menus as $menuIndex => $menu) {
            if (!is_array($menu)) {
                $errors['menus.' . $menuIndex] = '';
                continue;
            }

            $name = trim((string)($menu['name'] ?? ''));
            if ($name === '') {
                $errors['menus.' . $menuIndex . '.name'] = '';
            }

            $style = is_array($menu['style'] ?? null) ? $menu['style'] : [];
            $displayType = trim((string)($style['display_type'] ?? 'icon_text'));
            if (!in_array($displayType, self::DISPLAY_TYPES, true)) {
                $errors['menus.' . $menuIndex . '.style.display_type'] = '';
            }

            $items = is_array($menu['items'] ?? null) ? $menu['items'] : [];
            if (count($items) < 2) {
                $errors['menus.' . $menuIndex . '.items'] = '';
                continue;
            }

            if (count($items) > 5) {
                $errors['menus.' . $menuIndex . '.items_max'] = '';
            }

            foreach ($items as $itemIndex => $item) {
                if (!is_array($item)) {
                    $errors['menus.' . $menuIndex . '.items.' . $itemIndex] = '';
                    continue;
                }

                $label = trim((string)($item['label'] ?? ''));
                $linkId = (int)($item['link_id'] ?? 0);
                if ($label === '') {
                    $errors['menus.' . $menuIndex . '.items.' . $itemIndex . '.label'] = '';
                }
                if ($linkId <= 0 || !in_array($linkId, $linkIds, true)) {
                    $errors['menus.' . $menuIndex . '.items.' . $itemIndex . '.link_id'] = '';
                }


                if ($displayType !== 'text' && trim((string)($item['default_icon'] ?? '')) === '') {
                    $errors['menus.' . $menuIndex . '.items.' . $itemIndex . '.default_icon'] = '';
                }
                if ($displayType !== 'text' && trim((string)($item['active_icon'] ?? '')) === '') {
                    $errors['menus.' . $menuIndex . '.items.' . $itemIndex . '.active_icon'] = '';
                }
            }
        }

        return $errors;
    }
}