<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreMenuRequest;
use App\Http\Requests\UpdateMenuRequest;
use App\Services\MenuService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class MenuController extends Controller
{
    public function __construct(
        private readonly MenuService $menuService
    ) {}

    /**
     * 메뉴 목록 조회
     */
    public function index(Request $request): JsonResponse|\Illuminate\Http\Response
    {
        $tenantId = session('selected_tenant_id');
        $importMode = $request->get('mode') === 'import' && $tenantId;

        if ($importMode) {
            // 가져오기 모드: 전체 글로벌 메뉴 (가져오기 상태 포함)
            $menus = $this->menuService->getAllGlobalMenusWithStatus($tenantId);
        } else {
            // 일반 모드: 현재 범위의 메뉴 목록
            $menus = $this->menuService->getMenus(
                $request->all(),
                $request->integer('per_page', 10)
            );
        }

        // HTMX 요청인 경우 HTML 직접 반환
        if ($request->header('HX-Request')) {
            return response(view('menus.partials.table', compact('menus', 'importMode')));
        }

        // 일반 API 요청인 경우 JSON 반환
        if ($importMode) {
            return response()->json([
                'success' => true,
                'data' => $menus,
                'importMode' => true,
            ]);
        }

        return response()->json([
            'success' => true,
            'data' => $menus->items(),
            'meta' => [
                'current_page' => $menus->currentPage(),
                'last_page' => $menus->lastPage(),
                'per_page' => $menus->perPage(),
                'total' => $menus->total(),
            ],
        ]);
    }

    /**
     * 메뉴 트리 구조 조회
     */
    public function tree(Request $request): JsonResponse
    {
        $tenantId = $request->integer('tenant_id') ?: session('selected_tenant_id');
        $tree = $this->menuService->getMenuTree($tenantId);

        return response()->json([
            'success' => true,
            'data' => $tree,
        ]);
    }

    /**
     * 메뉴 상세 조회
     */
    public function show(int $id): JsonResponse
    {
        $menu = $this->menuService->getMenuById($id);

        if (! $menu) {
            return response()->json([
                'success' => false,
                'message' => '메뉴를 찾을 수 없습니다.',
            ], 404);
        }

        return response()->json([
            'success' => true,
            'data' => $menu,
        ]);
    }

    /**
     * 메뉴 생성
     */
    public function store(StoreMenuRequest $request): JsonResponse
    {
        try {
            $menu = $this->menuService->createMenu($request->validated());

            return response()->json([
                'success' => true,
                'message' => '메뉴가 생성되었습니다.',
                'data' => $menu,
                'redirect' => route('menus.index'),
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 생성에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 수정
     */
    public function update(UpdateMenuRequest $request, int $id): JsonResponse
    {
        try {
            $result = $this->menuService->updateMenu($id, $request->validated());

            if (! $result) {
                return response()->json([
                    'success' => false,
                    'message' => '메뉴를 찾을 수 없거나 수정할 수 없습니다.',
                ], 404);
            }

            return response()->json([
                'success' => true,
                'message' => '메뉴가 수정되었습니다.',
                'redirect' => route('menus.index'),
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 수정에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 삭제
     */
    public function destroy(int $id): JsonResponse
    {
        try {
            $result = $this->menuService->deleteMenu($id);

            if (! $result) {
                return response()->json([
                    'success' => false,
                    'message' => '메뉴를 찾을 수 없거나 자식 메뉴가 있어 삭제할 수 없습니다.',
                ], 404);
            }

            return response()->json([
                'success' => true,
                'message' => '메뉴가 삭제되었습니다.',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 삭제에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 복원
     */
    public function restore(Request $request, int $id): JsonResponse
    {
        $this->menuService->restoreMenu($id);

        // HTMX 요청 시 테이블 새로고침 트리거
        if ($request->header('HX-Request')) {
            return response()->json([
                'success' => true,
                'message' => '메뉴가 복원되었습니다.',
                'action' => 'refresh',
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => '메뉴가 복원되었습니다.',
        ]);
    }

    /**
     * 메뉴 영구 삭제 (슈퍼관리자 전용)
     * - 연관 권한도 함께 삭제
     * - 삭제 정보는 archived_records에 저장
     */
    public function forceDestroy(Request $request, int $id): JsonResponse
    {
        // 슈퍼관리자 권한 체크
        if (! auth()->user()?->is_super_admin) {
            return response()->json([
                'success' => false,
                'message' => '권한이 없습니다.',
            ], 403);
        }

        try {
            $result = $this->menuService->forceDeleteMenu($id);

            if (! $result['success']) {
                return response()->json([
                    'success' => false,
                    'message' => $result['message'],
                ], 400);
            }

            // HTMX 요청 시 테이블 새로고침 트리거
            if ($request->header('HX-Request')) {
                return response()->json([
                    'success' => true,
                    'message' => $result['message'],
                    'action' => 'refresh',
                    'deleted_permissions' => $result['deleted_permissions'],
                    'batch_id' => $result['batch_id'] ?? null,
                ]);
            }

            return response()->json([
                'success' => true,
                'message' => $result['message'],
                'deleted_permissions' => $result['deleted_permissions'],
                'batch_id' => $result['batch_id'] ?? null,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 영구 삭제에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 활성 상태 토글
     */
    public function toggleActive(Request $request, int $id): JsonResponse
    {
        try {
            $result = $this->menuService->toggleActive($id);

            if (! $result) {
                return response()->json([
                    'success' => false,
                    'message' => '메뉴를 찾을 수 없습니다.',
                ], 404);
            }

            // HTMX 요청 시 테이블 새로고침 트리거
            if ($request->header('HX-Request')) {
                return response()->json([
                    'success' => true,
                    'message' => '메뉴 활성 상태가 변경되었습니다.',
                    'action' => 'refresh',
                ]);
            }

            return response()->json([
                'success' => true,
                'message' => '메뉴 활성 상태가 변경되었습니다.',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 활성 상태 변경에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 숨김 상태 토글
     */
    public function toggleHidden(Request $request, int $id): JsonResponse
    {
        try {
            $result = $this->menuService->toggleHidden($id);

            if (! $result) {
                return response()->json([
                    'success' => false,
                    'message' => '메뉴를 찾을 수 없습니다.',
                ], 404);
            }

            // HTMX 요청 시 테이블 새로고침 트리거
            if ($request->header('HX-Request')) {
                return response()->json([
                    'success' => true,
                    'message' => '메뉴 숨김 상태가 변경되었습니다.',
                    'action' => 'refresh',
                ]);
            }

            return response()->json([
                'success' => true,
                'message' => '메뉴 숨김 상태가 변경되었습니다.',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 숨김 상태 변경에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 순서 변경 (드래그앤드롭)
     */
    public function reorder(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'items' => 'required|array',
            'items.*.id' => 'required|integer',
            'items.*.sort_order' => 'required|integer',
        ]);

        try {
            $this->menuService->reorderMenus($validated['items']);

            return response()->json([
                'success' => true,
                'message' => '메뉴 순서가 변경되었습니다.',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 순서 변경에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 메뉴 이동 (계층 구조 변경)
     */
    public function move(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'menu_id' => 'required|integer',
            'new_parent_id' => 'nullable|integer',
            'sort_order' => 'required|integer|min:1',
        ]);

        try {
            $result = $this->menuService->moveMenu(
                $validated['menu_id'],
                $validated['new_parent_id'],
                $validated['sort_order']
            );

            if (! $result['success']) {
                return response()->json($result, 400);
            }

            return response()->json($result);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 이동에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 글로벌 메뉴 목록 조회 (가져오기 상태 포함)
     */
    public function availableGlobal(Request $request): JsonResponse
    {
        $tenantId = session('selected_tenant_id');

        if (! $tenantId) {
            return response()->json([
                'success' => false,
                'message' => '테넌트를 선택해주세요.',
                'menus' => [],
            ], 400);
        }

        try {
            $menus = $this->menuService->getAllGlobalMenusWithStatus($tenantId);

            return response()->json([
                'success' => true,
                'menus' => $menus->map(function ($menu) {
                    return [
                        'id' => $menu->id,
                        'name' => $menu->name,
                        'url' => $menu->url,
                        'icon' => $menu->icon,
                        'depth' => $menu->depth ?? 0,
                        'is_imported' => $menu->is_imported ?? false,
                    ];
                })->values(),
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 목록 조회에 실패했습니다: '.$e->getMessage(),
                'menus' => [],
            ], 500);
        }
    }

    /**
     * 선택한 글로벌 메뉴를 현재 테넌트로 복사
     */
    public function copyFromGlobal(Request $request): JsonResponse
    {
        $tenantId = session('selected_tenant_id');

        if (! $tenantId) {
            return response()->json([
                'success' => false,
                'message' => '테넌트를 선택해주세요.',
                'copied' => 0,
            ], 400);
        }

        $validated = $request->validate([
            'menu_ids' => 'required|array|min:1',
            'menu_ids.*' => 'required|integer',
        ]);

        try {
            $result = $this->menuService->copyFromGlobal($tenantId, $validated['menu_ids']);

            if (! $result['success']) {
                return response()->json($result, 400);
            }

            return response()->json($result);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 복사에 실패했습니다: '.$e->getMessage(),
                'copied' => 0,
            ], 500);
        }
    }

    /**
     * 선택 삭제 (일괄 soft delete)
     */
    public function bulkDelete(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'menu_ids' => 'required|array|min:1',
            'menu_ids.*' => 'required|integer',
        ]);

        try {
            $deleted = 0;
            foreach ($validated['menu_ids'] as $menuId) {
                if ($this->menuService->deleteMenu($menuId)) {
                    $deleted++;
                }
            }

            return response()->json([
                'success' => true,
                'message' => "{$deleted}개 메뉴가 삭제되었습니다.",
                'deleted' => $deleted,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 삭제에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 선택 복원 (일괄 restore)
     */
    public function bulkRestore(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'menu_ids' => 'required|array|min:1',
            'menu_ids.*' => 'required|integer',
        ]);

        try {
            $restored = 0;
            foreach ($validated['menu_ids'] as $menuId) {
                $this->menuService->restoreMenu($menuId);
                $restored++;
            }

            return response()->json([
                'success' => true,
                'message' => "{$restored}개 메뉴가 복원되었습니다.",
                'restored' => $restored,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 복원에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }

    /**
     * 선택 영구삭제 (일괄 force delete, 슈퍼관리자 전용)
     */
    public function bulkForceDelete(Request $request): JsonResponse
    {
        // 슈퍼관리자 권한 체크
        if (! auth()->user()?->is_super_admin) {
            return response()->json([
                'success' => false,
                'message' => '권한이 없습니다.',
            ], 403);
        }

        $validated = $request->validate([
            'menu_ids' => 'required|array|min:1',
            'menu_ids.*' => 'required|integer',
        ]);

        try {
            $deleted = 0;
            $totalPermissions = 0;

            foreach ($validated['menu_ids'] as $menuId) {
                $result = $this->menuService->forceDeleteMenu($menuId);
                if ($result['success']) {
                    $deleted++;
                    $totalPermissions += count($result['deleted_permissions'] ?? []);
                }
            }

            return response()->json([
                'success' => true,
                'message' => "{$deleted}개 메뉴가 영구 삭제되었습니다. (연관 권한 {$totalPermissions}개 삭제)",
                'deleted' => $deleted,
                'deleted_permissions' => $totalPermissions,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => '메뉴 영구삭제에 실패했습니다: '.$e->getMessage(),
            ], 500);
        }
    }
}
