<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PermissionController extends Controller
{
    // 權限角色設定
    public function roles()
    {
        $per_page = request()->input('roles_per_page', request()->input('per_page', 10));
        $user = auth()->user();
        $query = \App\Models\System\Role::query()->with(['permissions', 'users', 'company']);

        // 租戶隔離：租戶只能看到自己公司的角色
        if (!$user->isSystemAdmin()) {
            $query->where('company_id', $user->company_id);
        }

        // 搜尋：角色名稱（支援 roles_search 命名空間 與舊版 search）
        $search = request()->input('roles_search', request()->input('search'));
        if ($search) {
            $query->where('name', 'like', "%{$search}%");
        }

        // 篩選：公司名稱（支援 roles_company_id 命名空間 與舊版 company_id）
        $company_id = request()->input('roles_company_id', request()->input('company_id'));
        if ($user->isSystemAdmin() && filled($company_id)) {
            if ($company_id === 'system') {
                $query->whereNull('company_id');
            } else {
                $query->where('company_id', $company_id);
            }
        }

        $roles = $query->latest()->paginate($per_page, ['*'], 'roles_page')->withQueryString();
        $companies = $user->isSystemAdmin() ? \App\Models\System\Company::all() : collect();
        
        // 權限分組邏輯中的標題與過濾
        $isSubAccountRoles = request()->routeIs('*.sub-account-roles');
        $title = $isSubAccountRoles ? __('Sub Account Roles') : __('Role Settings');
        $permissionQuery = \Spatie\Permission\Models\Permission::query();
        if (!$user->isSystemAdmin()) {
            $permissionQuery->whereIn('name', $user->getAllPermissions()->pluck('name'));
        }

        // 權限分組邏輯
        $all_permissions = $permissionQuery->get()
            ->reject(fn($p) => $p->name === 'menu.data-config.sub-account-roles')
            ->groupBy(function($perm) {
                if (str_starts_with($perm->name, 'menu.')) {
                    return 'menu';
                }
                return 'other';
            });

        $currentUserRoleIds = $user->roles->pluck('id')->toArray();
        return view('admin.permission.roles', compact('roles', 'all_permissions', 'title', 'currentUserRoleIds', 'companies'));
    }

    /**
     * Show the form for creating a new role.
     */
    public function createRole()
    {
        $role = new \App\Models\System\Role();
        $user = auth()->user();

        // 權限遞迴約束由 getFilteredPermissions 處理

        $all_permissions = $this->getFilteredPermissions($user);

        $title = request()->routeIs('*.sub-account-roles.create') ? __('Create Sub Account Role') : __('Create New Role');
        $back_url = request()->routeIs('*.sub-account-roles.create') 
            ? route('admin.data-config.sub-accounts', ['tab' => 'roles']) 
            : route('admin.permission.roles');

        return view('admin.permission.roles-edit', compact('role', 'all_permissions', 'title', 'back_url'));
    }

    /**
     * Show the form for editing the specified role.
     */
    public function editRole($id)
    {
        $role = \App\Models\System\Role::findOrFail($id);
        $user = auth()->user();

        // 權限遞迴約束與分組邏輯由 getFilteredPermissions 處理

        $all_permissions = $this->getFilteredPermissions($user);

        // 根據路由決定標題
        $title = request()->routeIs('*.sub-account-roles.edit') ? __('Edit Sub Account Role') : __('Edit Role Permissions');
        
        // 麵包屑/返回路徑
        $back_url = request()->routeIs('*.sub-account-roles.edit') 
            ? route('admin.data-config.sub-accounts', ['tab' => 'roles']) 
            : route('admin.permission.roles');

        return view('admin.permission.roles-edit', compact('role', 'all_permissions', 'title', 'back_url'));
    }

    /**
     * Store a newly created role in storage.
     */
    public function storeRole(Request $request)
    {
        $is_system = auth()->user()->isSystemAdmin() && $request->boolean('is_system');
        $company_id = $is_system ? null : auth()->user()->company_id;

        $validated = $request->validate([
            'name' => [
                'required', 'string', 'max:255',
                \Illuminate\Validation\Rule::unique('roles', 'name')->where(function ($query) use ($company_id) {
                    return $query->where('company_id', $company_id);
                })
            ],
            'permissions' => 'nullable|array',
            'permissions.*' => 'string|exists:permissions,name',
        ]);

        $role = \App\Models\System\Role::query()->create([
            'name' => $validated['name'],
            'guard_name' => 'web',
            'company_id' => $is_system ? null : auth()->user()->company_id,
            'is_system' => $is_system,
        ]);

        if (!empty($validated['permissions'])) {
            $perms = $validated['permissions'];
            
            // 權限遞迴約束驗證
            if (!auth()->user()->isSystemAdmin()) {
                $currentUserPerms = auth()->user()->getAllPermissions()->pluck('name');
                if (collect($perms)->diff($currentUserPerms)->isNotEmpty()) {
                    return redirect()->back()->with('error', __('You cannot assign permissions you do not possess.'));
                }
            }

            // 如果不是系統角色，排除主選單的系統權限
            if (!$is_system) {
                $perms = array_diff($perms, ['menu.basic', 'menu.permissions']);
            }
            $role->syncPermissions($perms);
        }

        $target_route = request()->routeIs('*.sub-account-roles.*') ? route('admin.data-config.sub-accounts', ['tab' => 'roles']) : route('admin.permission.roles');
        return redirect()->to($target_route)->with('success', __('Role created successfully.'));
    }

    /**
     * Update the specified role in storage.
     */
    public function updateRole(Request $request, $id)
    {
        $role = \App\Models\System\Role::findOrFail($id);

        $is_system = $role->is_system;
        $company_id = $role->company_id;

        $validated = $request->validate([
            'name' => [
                'required', 'string', 'max:255',
                \Illuminate\Validation\Rule::unique('roles', 'name')
                    ->ignore($id)
                    ->where(function ($query) use ($company_id) {
                        return $query->where('company_id', $company_id);
                    })
            ],
            'permissions' => 'nullable|array',
            'permissions.*' => 'string|exists:permissions,name',
        ]);

        if ($role->name === 'super-admin') {
             return redirect()->back()->with('error', __('The Super Admin role is immutable.'));
        }

        if (!auth()->user()->isSystemAdmin() && $role->is_system) {
             return redirect()->back()->with('error', __('System roles cannot be modified by tenant administrators.'));
        }

        $is_system = auth()->user()->isSystemAdmin() ? $request->boolean('is_system') : $role->is_system;

        $updateData = [
            'name' => $validated['name'],
            'is_system' => $is_system,
            'company_id' => $is_system ? null : $role->company_id,
        ];

        $role->update($updateData);

        $perms = $validated['permissions'] ?? [];

        // 權限遞迴約束驗證
        if (!auth()->user()->isSystemAdmin()) {
            $currentUserPerms = auth()->user()->getAllPermissions()->pluck('name');
            if (collect($perms)->diff($currentUserPerms)->isNotEmpty()) {
                return redirect()->back()->with('error', __('You cannot assign permissions you do not possess.'));
            }
        }

        // 如果不是系統角色，排除主選單的系統權限
        if (!$is_system) {
            $perms = array_diff($perms, ['menu.basic', 'menu.permissions']);
        }
        $role->syncPermissions($perms);

        $target_route = request()->routeIs('*.sub-account-roles.*') ? route('admin.data-config.sub-accounts', ['tab' => 'roles']) : route('admin.permission.roles');
        return redirect()->to($target_route)->with('success', __('Role updated successfully.'));
    }

    /**
     * Remove the specified role from storage.
     */
    public function destroyRole($id)
    {
        $role = \App\Models\System\Role::findOrFail($id);

        if ($role->name === 'super-admin') {
            return redirect()->back()->with('error', __('The Super Admin role cannot be deleted.'));
        }

        if (!auth()->user()->isSystemAdmin() && $role->is_system) {
            return redirect()->back()->with('error', __('System roles cannot be deleted by tenant administrators.'));
        }

        if ($role->users()->count() > 0) {
            return redirect()->back()->with('error', __('Cannot delete role with active users.'));
        }

        $role->delete();

        if (request()->routeIs('*.sub-account-roles.*')) {
            return redirect()->route('admin.data-config.sub-accounts', ['tab' => 'roles'])->with('success', __('Role deleted successfully.'));
        }

        return redirect()->back()->with('success', __('Role deleted successfully.'));
    }

    // 帳號管理
    public function accounts(Request $request)
    {
        $user = auth()->user();
        $isSubAccountRoute = $request->routeIs('admin.data-config.sub-accounts');
        $tab = $request->input('tab', 'accounts'); // 僅用於設定 Alpine activeTab 初始值

        $companies = $user->isSystemAdmin() ? \App\Models\System\Company::all() : collect();
        $currentUserRoleIds = $user->roles->pluck('id')->toArray();

        // ── 帳號列表 ──────────────────────────────────────────────────
        $usersQuery = \App\Models\System\User::query()->with(['company', 'roles', 'machines']);
        if (!$user->isSystemAdmin()) {
            $usersQuery->where('company_id', $user->company_id);
        }
        if ($search = $request->input('accounts_search', $request->input('search'))) {
            $usersQuery->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('username', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }
        if ($user->isSystemAdmin() && $request->filled('accounts_company_id')) {
            $cid = $request->input('accounts_company_id');
            $cid === 'system' ? $usersQuery->whereNull('company_id') : $usersQuery->where('company_id', $cid);
        }
        $accounts_per_page = $request->input('accounts_per_page', 10);
        $users = $usersQuery->latest()->paginate($accounts_per_page, ['*'], 'accounts_page')->withQueryString();

        // Modal 用的角色選單（不分頁）
        $rolesForSelect = \App\Models\System\Role::query();
        if (!$user->isSystemAdmin()) {
            $rolesForSelect->forCompany($user->company_id);
        }
        $roles = $rolesForSelect->get();

        // ── 角色列表 (僅 data-config Tab 版需要) ─────────────────────
        $paginated_roles = collect();
        $all_permissions = collect();

        if ($isSubAccountRoute) {
            $rolesQuery = \App\Models\System\Role::query()->with(['permissions', 'users', 'company']);
            if (!$user->isSystemAdmin()) {
                $rolesQuery->where('company_id', $user->company_id);
            }
            if ($search = $request->input('roles_search')) {
                $rolesQuery->where('name', 'like', "%{$search}%");
            }
            if ($user->isSystemAdmin() && $request->filled('roles_company_id')) {
                $cid = $request->input('roles_company_id');
                $cid === 'system' ? $rolesQuery->where('is_system', true) : $rolesQuery->where('company_id', $cid);
            }
            $roles_per_page = $request->input('roles_per_page', 10);
            $paginated_roles = $rolesQuery->latest()->paginate($roles_per_page, ['*'], 'roles_page')->withQueryString();

            $permissionQuery = \Spatie\Permission\Models\Permission::query();
            if (!$user->isSystemAdmin()) {
                $permissionQuery->whereIn('name', $user->getAllPermissions()->pluck('name'));
            }
            $all_permissions = $permissionQuery->get()
                ->reject(fn($p) => $p->name === 'menu.data-config.sub-account-roles')
                ->groupBy(fn($p) => str_starts_with($p->name, 'menu.') ? 'menu' : 'other');
        }

        $title = $isSubAccountRoute ? __('Sub Account Management') : __('Account Management');
        $view  = $isSubAccountRoute ? 'admin.data-config.accounts' : 'admin.permission.accounts';

        return view($view, compact(
            'users', 'companies', 'roles', 'paginated_roles', 'all_permissions', 'title', 'tab', 'currentUserRoleIds'
        ));
    }

    /**
     * Store a newly created account in storage.
     */
    public function storeAccount(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'username' => 'required|string|max:255|unique:users,username',
            'email' => 'nullable|email|max:255|unique:users,email',
            'password' => 'required|string|min:8',
            'role' => 'required|string',
            'status' => 'required|boolean',
            'company_id' => 'nullable|exists:companies,id',
            'phone' => 'nullable|string|max:20',
        ]);

        $company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;

        // 查找角色：優先尋找該公司的角色，若無則尋找全域範本
        $role = \App\Models\System\Role::where('name', $validated['role'])
            ->where(function($q) use ($company_id) {
                $q->where('company_id', $company_id)->orWhereNull('company_id');
            })
            ->first();

        if (!$role) {
            return redirect()->back()->with('error', __('Role not found.'));
        }

        // 驗證角色與公司的匹配性 (RBAC Safeguard)
        if ($company_id !== null) {
            // 如果是租戶帳號，絕對不能指派超級管理員角色 (super-admin)
            if ($role->name === 'super-admin') {
                return redirect()->back()->with('error', __('Super-admin role cannot be assigned to tenant accounts.'));
            }
            // 如果角色有特定的 company_id，必須匹配
            if ($role->company_id !== null && $role->company_id != $company_id) {
                return redirect()->back()->with('error', __('This role belongs to another company and cannot be assigned.'));
            }
        } else {
            // 如果是系統層級帳號，只能選全域系統角色 (is_system = 1)
            if (!$role->is_system) {
                return redirect()->back()->with('error', __('Only system roles can be assigned to platform administrative accounts.'));
            }
        }

        // 角色初始化與克隆邏輯 (只有 super-admin 在幫空白公司開帳號時觸發)
        $company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;

        if ($company_id && $role && $role->company_id === null && $role->name !== 'super-admin') {
            // 檢查該公司是否已有名為「管理員」的角色
            $existingRole = \App\Models\System\Role::where('company_id', $company_id)
                ->where('name', '管理員')
                ->first();

            if (!$existingRole) {
                // 克隆範本為該公司的「管理員」
                $newRole = \App\Models\System\Role::query()->create([
                    'name' => '管理員',
                    'guard_name' => 'web',
                    'company_id' => $company_id,
                    'is_system' => false,
                ]);
                $newRole->syncPermissions($role->getPermissionNames());
                $role = $newRole;
            } else {
                // 如果已存在名為「管理員」的角色，則直接使用它
                $role = $existingRole;
            }
        }

        $user = \App\Models\System\User::create([
            'name' => $validated['name'],
            'username' => $validated['username'],
            'email' => $validated['email'],
            'password' => \Illuminate\Support\Facades\Hash::make($validated['password']),
            'status' => $validated['status'],
            'company_id' => $company_id,
            'phone' => $validated['phone'] ?? null,
            'is_admin' => (auth()->user()->isSystemAdmin() && !empty($validated['company_id'])),
        ]);

        $user->assignRole($role);

        return redirect()->back()->with('success', __('Account created successfully.'));
    }

    /**
     * Update the specified account in storage.
     */
    public function updateAccount(Request $request, $id)
    {
        $user = \App\Models\System\User::findOrFail($id);

        if ($user->hasRole('super-admin') && !auth()->user()->hasRole('super-admin')) {
            return redirect()->back()->with('error', __('System super admin accounts can only be modified by other super admins.'));
        }

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'username' => 'required|string|max:255|unique:users,username,' . $id,
            'email' => 'nullable|email|max:255|unique:users,email,' . $id,
            'password' => 'nullable|string|min:8',
            'role' => 'required|string',
            'status' => 'required|boolean',
            'company_id' => 'nullable|exists:companies,id',
            'phone' => 'nullable|string|max:20',
        ]);

        $target_company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;

        // 查找角色：優先尋找該公司的角色，若無則尋找全域範本
        $roleObj = \App\Models\System\Role::where('name', $validated['role'])
            ->where(function($q) use ($target_company_id) {
                $q->where('company_id', $target_company_id)->orWhereNull('company_id');
            })
            ->first();

        if (!$roleObj) {
            return redirect()->back()->with('error', __('Role not found.'));
        }

        // 驗證角色與公司的匹配性 (RBAC Safeguard)
        if ($user->id !== auth()->id()) { // 排除編輯自己 (super-admin 有特殊邏輯)
            if ($target_company_id !== null) {
                // 租戶層級排除 super-admin
                if ($roleObj->name === 'super-admin') {
                    return redirect()->back()->with('error', __('Super-admin role cannot be assigned to tenant accounts.'));
                }
                if ($roleObj->company_id !== null && $roleObj->company_id != $target_company_id) {
                    return redirect()->back()->with('error', __('This role belongs to another company and cannot be assigned.'));
                }
            } else {
                if (!$roleObj->is_system) {
                    return redirect()->back()->with('error', __('Only global system roles can be assigned to platform administrative accounts.'));
                }
            }
        }

        $updateData = [
            'name' => $validated['name'],
            'username' => $validated['username'],
            'email' => $validated['email'],
            'status' => $validated['status'],
            'phone' => $validated['phone'] ?? null,
        ];

        // 只有系統管理員在編輯租戶帳號時，且該帳號原本不是管理員，才可能觸發標記（視需求而定）
        // 這裡我們維持 storeAccount 的邏輯：如果是系統管理員幫公司「開站」或「首配」，才自動標記
        // 為求嚴謹，我們檢查該公司是否已經有 is_admin，如果沒有，當前這個人可以是第一個
        if (auth()->user()->isSystemAdmin() && !empty($validated['company_id']) && !$user->is_admin) {
            $hasAdmin = \App\Models\System\User::where('company_id', $validated['company_id'])
                ->where('is_admin', true)
                ->exists();
            if (!$hasAdmin) {
                $updateData['is_admin'] = true;
            }
        }

        if (auth()->user()->isSystemAdmin()) {
            // 防止超級管理員不小心把自己綁定到租客公司或降級
            if ($user->id === auth()->id()) {
                $updateData['company_id'] = null;
                $validated['role'] = 'super-admin';
            } else {
                $updateData['company_id'] = $validated['company_id'];
            }
        }

        if (!empty($validated['password'])) {
            $updateData['password'] = \Illuminate\Support\Facades\Hash::make($validated['password']);
        }

        // 角色初始化與克隆邏輯
        $target_company_id = auth()->user()->isSystemAdmin() ? ($validated['company_id'] ?? null) : auth()->user()->company_id;

        if ($target_company_id && $roleObj && $roleObj->company_id === null && $roleObj->name !== 'super-admin') {
            // 檢查該公司是否已有名為「管理員」的角色
            $existingRole = \App\Models\System\Role::where('company_id', $target_company_id)
                ->where('name', '管理員')
                ->first();

            if (!$existingRole) {
                $newRole = \App\Models\System\Role::query()->create([
                    'name' => '管理員',
                    'guard_name' => 'web',
                    'company_id' => $target_company_id,
                    'is_system' => false,
                    'is_admin' => true,
                ]);
                $newRole->syncPermissions($roleObj->getPermissionNames());
                $roleObj = $newRole;
            } else {
                $roleObj = $existingRole;
            }
        }

        $user->update($updateData);

        // 如果是編輯自己且原本是超級管理員，強制保留 super-admin 角色
        if ($user->id === auth()->id() && auth()->user()->isSystemAdmin()) {
            $user->syncRoles(['super-admin']);
        } else {
            $user->syncRoles([$roleObj]);
        }

        return redirect()->back()->with('success', __('Account updated successfully.'));
    }

    /**
     * Remove the specified account from storage.
     */
    public function destroyAccount($id)
    {
        $user = \App\Models\System\User::findOrFail($id);
        
        if ($user->hasRole('super-admin') && !auth()->user()->hasRole('super-admin')) {
            return redirect()->back()->with('error', __('System super admin accounts can only be deleted by other super admins.'));
        }

        if ($user->id === auth()->id()) {
            return redirect()->back()->with('error', __('You cannot delete your own account.'));
        }

        // 為了解決軟刪除導致的唯一索引佔用問題，刪除前先重命名唯一欄位
        $timestamp = now()->getTimestamp();
        $user->username = $user->username . '.deleted.' . $timestamp;
        $user->email = $user->email . '.deleted.' . $timestamp;
        $user->save();

        $user->delete();

        return redirect()->back()->with('success', __('Account deleted successfully.'));
    }

    public function toggleAccountStatus($id)
    {
        $user = \App\Models\System\User::findOrFail($id);
        
        // 非超級管理員禁止切換 Super Admin 狀態
        if ($user->hasRole('super-admin') && !auth()->user()->hasRole('super-admin')) {
            return back()->with('error', __('Only Super Admins can change other Super Admin status.'));
        }

        $user->status = $user->status ? 0 : 1;
        $user->save();

        $statusText = $user->status ? __('Enabled') : __('Disabled');
        return back()->with('success', __('Account :name status has been changed to :status.', ['name' => $user->name, 'status' => $statusText]));
    }

    /**
     * 獲取過濾後的活動模組權限清單
     */
    private function getFilteredPermissions($user)
    {
        $permissionQuery = \Spatie\Permission\Models\Permission::query();
        if (!$user->isSystemAdmin()) {
            $permissionQuery->whereIn('name', $user->getAllPermissions()->pluck('name'));
        }

        $activeModules = [
            'menu.machines',
            'menu.warehouses',
            'menu.sales',
            'menu.analysis',
            'menu.data-config',
            'menu.remote',
            'menu.basic',
            'menu.permissions',
        ];

        return $permissionQuery->get()
            ->filter(function($p) use ($activeModules) {
                if (str_starts_with($p->name, 'menu.')) {
                    foreach ($activeModules as $module) {
                        if ($p->name === $module || str_starts_with($p->name, $module . '.')) {
                            return true;
                        }
                    }
                    return false;
                }
                return true;
            })
            ->reject(fn($p) => $p->name === 'menu.data-config.sub-account-roles')
            ->groupBy(function($perm) {
                if (str_starts_with($perm->name, 'menu.')) {
                    return 'menu';
                }
                return 'other';
            });
    }
}
