<?php

namespace App\Console\Commands;

use App\Models\Branch;
use App\Models\Department;
use App\Models\Dealer;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class RepairProvisionedDealerUsers extends Command
{
    protected $signature = 'dealers:repair-provisioned-users
                            {--dry-run : List changes without applying them}';

    protected $description = 'Repair provisioned dealers: assign users with null branch_id to default branch, and Dealer Administrator users with null department_id to Admin (idempotent).';

    public function handle(): int
    {
        $dryRun = (bool) $this->option('dry-run');
        $tableNames = config('permission.table_names', []);
        $rolesTable = $tableNames['roles'] ?? 'roles';
        $modelHasRolesTable = $tableNames['model_has_roles'] ?? 'model_has_roles';
        $teamKey = config('permission.column_names.team_foreign_key', 'dealer_id');

        $dealers = Dealer::query()->get();
        if ($dealers->isEmpty()) {
            $this->info('No dealers found.');

            return self::SUCCESS;
        }

        $branchFixed = 0;
        $departmentFixed = 0;

        foreach ($dealers as $dealer) {
            $defaultBranch = Branch::withoutGlobalScope('dealer_scope')
                ->where('dealer_id', $dealer->id)
                ->where('is_default', true)
                ->first();

            // 1. Assign users with null branch_id to this dealer's default branch (only when default branch exists).
            if ($defaultBranch !== null) {
                $branchless = User::query()
                    ->where('dealer_id', $dealer->id)
                    ->whereNull('branch_id')
                    ->get();

                foreach ($branchless as $user) {
                    if ($dryRun) {
                        $this->line("[dry-run] Would set user [{$user->id}] {$user->email} branch_id => {$defaultBranch->id} (dealer {$dealer->id}).");
                    } else {
                        $user->branch_id = $defaultBranch->id;
                        $user->save();
                    }
                    $branchFixed++;
                }
            }

            // 2. Assign Dealer Administrator users with null department_id to this dealer's Admin department.
            $adminDepartment = Department::withoutGlobalScopes()
                ->where('dealer_id', $dealer->id)
                ->where('name', 'Admin')
                ->first();

            if ($adminDepartment === null) {
                continue;
            }

            $dealerAdminUserIds = DB::table($modelHasRolesTable.' as mhr')
                ->join($rolesTable.' as r', 'r.id', '=', 'mhr.role_id')
                ->where('mhr.model_type', User::class)
                ->where('mhr.'.$teamKey, $dealer->id)
                ->where('r.'.$teamKey, $dealer->id)
                ->where('r.name', 'Dealer Administration')
                ->pluck('mhr.model_id')
                ->unique()
                ->values()
                ->all();

            if ($dealerAdminUserIds === []) {
                continue;
            }

            $dealerAdminsWithoutDept = User::query()
                ->whereIn('id', $dealerAdminUserIds)
                ->where('dealer_id', $dealer->id)
                ->whereNull('department_id')
                ->get();

            foreach ($dealerAdminsWithoutDept as $user) {
                if ($dryRun) {
                    $this->line("[dry-run] Would set user [{$user->id}] {$user->email} department_id => {$adminDepartment->id} (Admin, dealer {$dealer->id}).");
                } else {
                    $user->department_id = $adminDepartment->id;
                    $user->save();
                }
                $departmentFixed++;
            }
        }

        if ($dryRun) {
            $this->info("[dry-run] Would fix branch_id for {$branchFixed} user(s) and department_id for {$departmentFixed} Dealer Administrator user(s).");
        } else {
            $this->info("Fixed branch_id for {$branchFixed} user(s) and department_id for {$departmentFixed} Dealer Administrator user(s).");
        }

        return self::SUCCESS;
    }
}
