<?php

namespace App\Services;

use App\Http\Responses\ApiResponse;
use App\Models\AdminMenu;
use Illuminate\Support\Facades\DB;

class MenuService
{
    public function index(array $params)
    {
        $query = AdminMenu::orderBy('sort', 'asc')->orderBy('id', 'desc');

        if (! empty($params['terminal'])) {
            $query->where('terminal_type', $params['terminal']);
        }

        $menus = $query->get();
        $tree = $this->buildTree($menus->toArray());

        return ApiResponse::success($tree);
    }

    public function tree(?string $terminalType = null)
    {
        $query = AdminMenu::where('status', 1)->orderBy('sort', 'asc');

        if ($terminalType !== null && $terminalType !== '') {
            $query->where('terminal_type', $terminalType);
        }

        $menus = $query->get();
        $tree = $this->buildTree($menus->toArray());

        return ApiResponse::success($tree);
    }

    public function userMenus()
    {
        $user = auth('admin')->user();

        if ($user->isSuperAdmin()) {
            $menus = AdminMenu::where('status', 1)
                ->where('visible', 1)
                ->orderBy('sort', 'asc')
                ->get();
        } else {
            $menus = AdminMenu::whereHas('roles', function ($query) use ($user) {
                $query->whereIn('admin_roles.id', $user->roles->pluck('id'));
            })
                ->where('status', 1)
                ->where('visible', 1)
                ->orderBy('sort', 'asc')
                ->get();
        }

        $tree = $this->buildTree($menus->toArray());

        return ApiResponse::success($tree);
    }

    protected function buildTree(array $items, int $parentId = 0): array
    {
        $tree = [];
        foreach ($items as $item) {
            if (($item['parent_id'] ?? 0) == $parentId) {
                $children = $this->buildTree($items, $item['id']);
                if ($children) {
                    $item['children'] = $children;
                }
                $tree[] = $item;
            }
        }

        return $tree;
    }

    public function store(array $data)
    {
        $menu = AdminMenu::create([
            'parent_id' => $data['parent_id'] ?? 0,
            'name' => $data['name'],
            'icon' => $data['icon'] ?? null,
            'path' => $data['path'] ?? null,
            'component' => $data['component'] ?? null,
            'permission_code' => $data['permission_code'] ?? null,
            'type' => $data['type'] ?? 1,
            'visible' => $data['visible'] ?? 1,
            'sort' => $data['sort'] ?? 0,
            'status' => $data['status'] ?? 1,
            'terminal_type' => $data['terminal_type'] ?? 'admin',
        ]);

        return ApiResponse::success($menu, '创建成功');
    }

    public function show(int $id)
    {
        $menu = AdminMenu::find($id);

        if (! $menu) {
            return ApiResponse::error(40302, '菜单不存在');
        }

        return ApiResponse::success($menu);
    }

    public function update(int $id, array $data)
    {
        $menu = AdminMenu::find($id);

        if (! $menu) {
            return ApiResponse::error(40302, '菜单不存在');
        }

        $menu->update([
            'parent_id' => $data['parent_id'] ?? $menu->parent_id,
            'name' => $data['name'],
            'icon' => $data['icon'] ?? $menu->icon,
            'path' => $data['path'] ?? $menu->path,
            'component' => $data['component'] ?? $menu->component,
            'permission_code' => $data['permission_code'] ?? $menu->permission_code,
            'type' => $data['type'] ?? $menu->type,
            'visible' => $data['visible'] ?? $menu->visible,
            'sort' => $data['sort'] ?? $menu->sort,
            'status' => $data['status'] ?? $menu->status,
            'terminal_type' => $data['terminal_type'] ?? $menu->terminal_type,
        ]);

        return ApiResponse::success($menu, '更新成功');
    }

    public function destroy(int $id)
    {
        $menu = AdminMenu::find($id);

        if (! $menu) {
            return ApiResponse::error(40302, '菜单不存在');
        }

        if (AdminMenu::where('parent_id', $id)->exists()) {
            return ApiResponse::error(40303, '该菜单下有子菜单，不可删除');
        }

        DB::transaction(function () use ($menu) {
            $menu->roles()->detach();
            $menu->delete();
        });

        return ApiResponse::success(null, '删除成功');
    }

    public function updateVisible(int $id, int $visible)
    {
        $menu = AdminMenu::find($id);

        if (! $menu) {
            return ApiResponse::error(40302, '菜单不存在');
        }

        $menu->update(['visible' => $visible]);

        return ApiResponse::success($menu, $visible === 1 ? '显示成功' : '隐藏成功');
    }

    public function updateStatus(int $id, int $status)
    {
        $menu = AdminMenu::find($id);

        if (! $menu) {
            return ApiResponse::error(40302, '菜单不存在');
        }

        $menu->update(['status' => $status]);

        return ApiResponse::success($menu, $status === 1 ? '启用成功' : '禁用成功');
    }

    public function homeMenus()
    {
        $menus = AdminMenu::where('status', 1)
            ->where('visible', 1)
            ->where('terminal_type', 'home')
            ->orderBy('sort', 'asc')
            ->get(['id', 'parent_id', 'name', 'path', 'icon', 'sort', 'visible']);

        $tree = $this->buildTree($menus->toArray());

        return ApiResponse::success($tree);
    }

    public function saveSort(array $ids, array $sorts)
    {
        foreach ($ids as $index => $id) {
            AdminMenu::where('id', $id)->update([
                'sort' => isset($sorts[$index]) ? intval($sorts[$index]) : 0,
            ]);
        }

        return ApiResponse::success(null, '排序保存成功');
    }
}
