<?php

namespace App\Services\Hr;

use App\Models\PerformanceCycle;
use App\Models\PerformanceReview;
use App\Models\User;
use App\Services\AuditService;
use Illuminate\Support\Facades\DB;

class PerformanceCycleService
{
    public function __construct(
        protected AuditService $audit
    ) {}

    public function launch(PerformanceCycle $cycle, int $actorId): PerformanceCycle
    {
        if ($cycle->status !== PerformanceCycle::STATUS_DRAFT) {
            throw new \RuntimeException('Only draft cycles can be launched.');
        }

        return DB::transaction(function () use ($cycle, $actorId) {
            $staff = User::withoutGlobalScopes()
                ->where('company_id', $cycle->company_id)
                ->forActiveDirectory()
                ->get(['id', 'report_to']);

            $created = 0;
            foreach ($staff as $employee) {
                $exists = PerformanceReview::withoutGlobalScopes()
                    ->where('company_id', $cycle->company_id)
                    ->where('user_id', $employee->id)
                    ->where('performance_cycle_id', $cycle->id)
                    ->exists();

                if ($exists) {
                    continue;
                }

                PerformanceReview::create([
                    'company_id' => $cycle->company_id,
                    'performance_cycle_id' => $cycle->id,
                    'user_id' => $employee->id,
                    'reviewer_id' => $employee->report_to,
                    'period' => $cycle->name,
                    'status' => 'pending',
                    'review_date' => $cycle->end_date,
                ]);
                $created++;
            }

            $cycle->update([
                'status' => PerformanceCycle::STATUS_ACTIVE,
                'launched_at' => now(),
            ]);

            $this->audit->log('performance_cycle.launched', $cycle, [
                'reviews_created' => $created,
            ], (int) $cycle->company_id, $actorId);

            return $cycle->fresh();
        });
    }

    public function close(PerformanceCycle $cycle, int $actorId): PerformanceCycle
    {
        if ($cycle->status !== PerformanceCycle::STATUS_ACTIVE) {
            throw new \RuntimeException('Only active cycles can be closed.');
        }

        $cycle->update([
            'status' => PerformanceCycle::STATUS_CLOSED,
            'closed_at' => now(),
        ]);

        $this->audit->log('performance_cycle.closed', $cycle, [], (int) $cycle->company_id, $actorId);

        return $cycle->fresh();
    }
}
