<?php

use App\Console\Commands\RunScheduledReports;
use App\Console\Commands\SendProactiveHrAlerts;
use App\Models\Company;
use App\Models\User;
use Illuminate\Support\Facades\Schedule;
use Database\Seeders\UserSeeder;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');

Artisan::command('demo:admin', function () {
    $this->info('Creating or resetting demo admin (admin@demo.local / password)...');
    $this->call(UserSeeder::class);
    $this->info('Done. You can log in with: admin@demo.local / password');
})->purpose('Create or reset demo admin user (admin@demo.local / password)');

Artisan::command('hrms:prune-user-sessions {--days=90}', function () {
    $days = max(1, (int) $this->option('days'));
    $count = app(\App\Services\UserSessionService::class)->pruneOlderThan($days);
    $this->info("Pruned {$count} user session audit row(s) older than {$days} days.");
})->purpose('Delete stale rows from user_sessions audit table');

Artisan::command('company:seed-roles {company_id : The company ID (e.g. 2)} {--assign-first-user : Assign first user of this company to admin role}', function () {
    $companyId = (int) $this->argument('company_id');
    $company = Company::withoutGlobalScopes()->find($companyId);
    if (! $company) {
        $this->error("Company with id {$companyId} not found.");
        return 1;
    }

    $this->info("Seeding default roles for company: {$company->name} (id: {$companyId})");

    try {
        $roles = \App\Services\TenantRoleService::syncAllDefaultRolesForCompany($companyId);
    } catch (\Throwable $e) {
        $this->error($e->getMessage());

        return 1;
    }

    foreach (['admin', 'hr', 'manager', 'finance', 'employee'] as $roleName) {
        $this->line('  - ' . $roleName . ' role OK');
    }

    if ($this->option('assign-first-user')) {
        $user = User::withoutGlobalScopes()->where('company_id', $companyId)->first();
        if ($user) {
            $user->update(['role_id' => $roles['admin']->id]);
            $this->info("Assigned first user (id: {$user->id}, email: {$user->email}) to admin role.");
        } else {
            $this->warn('No user found for this company to assign.');
        }
    }

    $this->info('Done. Users of this company need role_id set to one of these roles to access the dashboard.');
    return 0;
})->purpose('Create default roles (admin, hr, manager, finance, employee) for a company so tenant users can access the app');

Artisan::command('company:allow-all-modules {company_id : The company ID (e.g. 2)}', function () {
    $companyId = (int) $this->argument('company_id');
    $company = Company::withoutGlobalScopes()->find($companyId);
    if (! $company) {
        $this->error("Company with id {$companyId} not found.");
        return 1;
    }
    $plan = \App\Models\SubscriptionPlan::where('name', 'Free')->orWhere('default', 'yes')->first();
    if (! $plan) {
        $this->error('Free subscription plan not found. Run SubscriptionPlanSeeder first.');
        return 1;
    }
    $plan->update(['modules' => []]);
    $company->update(['subscription_plan_id' => $plan->id]);
    $this->info("Company {$company->name} (id: {$companyId}) is now on plan \"{$plan->name}\" (all modules allowed).");
    return 0;
})->purpose('Assign a company to the Default plan so all features are allowed (no module restriction)');

Artisan::command('leaves:sync-balances {company_id? : Optional company ID} {--year= : Leave year (defaults to current)}', function () {
    $ledger = app(\App\Services\Leave\LeaveLedgerService::class);
    $companyId = $this->argument('company_id') ? (int) $this->argument('company_id') : null;
    $year = $this->option('year') ? (int) $this->option('year') : $ledger->leaveYear();

    $companies = $companyId
        ? \App\Models\Company::withoutGlobalScopes()->where('id', $companyId)->get()
        : \App\Models\Company::withoutGlobalScopes()->where('status', 'active')->get();

    $total = 0;
    foreach ($companies as $company) {
        $count = $ledger->syncBalancesForCompany((int) $company->id, $year);
        $total += $count;
        $this->line("Company {$company->id} ({$company->name}): synced {$count} balance row(s).");
    }

    $this->info("Done. Synced {$total} balance row(s) for year {$year}.");
    return 0;
})->purpose('Backfill leave balances from existing leave data and annual allocations');

Artisan::command('leaves:accrue-monthly {company_id? : Optional company ID} {--month= : YYYY-MM (defaults to current month)}', function () {
    $ledger = app(\App\Services\Leave\LeaveLedgerService::class);
    $companyId = $this->argument('company_id') ? (int) $this->argument('company_id') : null;
    $asOf = $this->option('month')
        ? \Carbon\Carbon::parse($this->option('month') . '-01')->startOfMonth()
        : now()->startOfMonth();

    $processed = $ledger->runMonthlyAccrual($companyId, $asOf);
    $this->info("Monthly accrual complete. Credited {$processed} employee leave balance(s) for {$asOf->format('Y-m')}.");
    return 0;
})->purpose('Run monthly leave accrual for leave types configured with monthly accrual');

Artisan::command('leaves:carry-forward {company_id? : Optional company ID} {--from-year= : Source year (defaults to previous year)}', function () {
    $ledger = app(\App\Services\Leave\LeaveLedgerService::class);
    $companyId = $this->argument('company_id') ? (int) $this->argument('company_id') : null;
    $fromYear = $this->option('from-year') ? (int) $this->option('from-year') : ($ledger->leaveYear() - 1);

    $processed = $ledger->runCarryForward($companyId, $fromYear);
    $this->info("Carry forward complete. Processed {$processed} balance(s) from {$fromYear} to " . ($fromYear + 1) . '.');
    return 0;
})->purpose('Carry forward unused leave balances to the next year');

Artisan::command('hrms:reset-tenant-permissions {--company_id=*} {--assign_role=employee} {--dry-run}', function () {
    $this->info('Alias: hrms:reset-tenant-permissions → hrms:finance-migrate-permissions');

    return $this->call('hrms:finance-migrate-permissions', [
        '--company_id' => $this->option('company_id'),
        '--assign_role' => $this->option('assign_role'),
        '--dry-run' => $this->option('dry-run'),
    ]);
})->purpose('Migrate split finance permissions on existing tenants (alias)');

Schedule::command('leads:send-due-followup-reminders')->everyFiveMinutes();
Schedule::command('leaves:accrue-monthly')->monthlyOn(1, '01:00');
Schedule::command('leaves:carry-forward')->yearlyOn(1, 1, '02:00');
Schedule::command('employees:deactivate-past-lwd')->dailyAt('00:30');
Schedule::command('hrms:send-proactive-alerts')->weeklyOn(1, '08:00');
Schedule::command('hrms:run-scheduled-reports')->dailyAt('06:00');
Schedule::command('hrms:prune-user-sessions')->monthlyOn(1, '03:30');
Schedule::command('subscriptions:send-expiry-reminders')->dailyAt('08:30');
Schedule::command('subscriptions:suspend-expired')->dailyAt('01:15');
