<?php
declare(strict_types=1);

namespace CronJobs;

use App\Core\Database;

class CoachPaymentGeneratorJob
{
    private Database $db;
    public function __construct(Database $db) { $this->db = $db; }

    public function shouldRun(): bool
    {
        return (int) date('j') === 1; // 1st of month
    }

    public function run(): array
    {
        $period = date('Y-m', strtotime('-1 month'));
        $periodStart = $period . '-01';
        $periodEnd = date('Y-m-t', strtotime($periodStart));
        $generated = 0;

        $coaches = $this->db->select(
            "SELECT id, payment_model, session_rate, per_player_rate, monthly_rate
             FROM coaches
             WHERE is_active = 1 AND is_archived = 0"
        );

        foreach ($coaches as $coach) {
            $exists = $this->db->selectOne(
                "SELECT id FROM coach_payments WHERE coach_id = ? AND payment_period = ?",
                [(int) $coach['id'], $period]
            );
            if ($exists) {
                continue;
            }

            $sessionData = $this->db->selectOne("
                SELECT COUNT(*) AS sessions_count,
                       COALESCE(SUM(players_attended), 0) AS total_players
                FROM training_sessions
                WHERE coach_id = ?
                  AND session_date BETWEEN ? AND ?
                  AND status = 'completed'
            ", [(int) $coach['id'], $periodStart, $periodEnd]);

            $sessions = (int) ($sessionData['sessions_count'] ?? 0);
            $players = (int) ($sessionData['total_players'] ?? 0);
            $model = $coach['payment_model'] ?? 'monthly_fixed';

            $base = 0;
            $bonus = 0;
            $calculation = [];

            switch ($model) {
                case 'per_session':
                    $rate = (float) ($coach['session_rate'] ?? 0);
                    $base = $sessions * $rate;
                    $calculation = ['rate' => $rate, 'sessions' => $sessions];
                    break;

                case 'per_player':
                    $rate = (float) ($coach['per_player_rate'] ?? 0);
                    $base = $players * $rate;
                    $calculation = ['rate' => $rate, 'players' => $players];
                    break;

                case 'monthly_fixed':
                    $base = (float) ($coach['monthly_rate'] ?? 0);
                    $calculation = ['monthly_rate' => $base];
                    break;

                case 'hybrid':
                    $base = (float) ($coach['monthly_rate'] ?? 0);
                    $sessionRate = (float) ($coach['session_rate'] ?? 0);
                    $threshold = 12;
                    if ($sessions > $threshold) {
                        $bonus = ($sessions - $threshold) * $sessionRate;
                    }
                    $calculation = [
                        'base' => $base, 'threshold' => $threshold,
                        'extra_sessions' => max(0, $sessions - $threshold),
                        'session_rate' => $sessionRate,
                    ];
                    break;
            }

            $net = $base + $bonus;

            $this->db->insert('coach_payments', [
                'coach_id'             => (int) $coach['id'],
                'payment_period'       => $period,
                'payment_model'        => $model,
                'sessions_conducted'   => $sessions,
                'total_players_served' => $players,
                'base_amount'          => $base,
                'bonus'                => $bonus,
                'deductions'           => 0,
                'net_amount'           => $net,
                'calculation_json'     => json_encode($calculation, JSON_UNESCAPED_UNICODE),
                'status'               => 'draft',
            ]);
            $generated++;
        }

        return [
            'status'  => 'success',
            'message' => "Generated {$generated} coach payment records for {$period}.",
        ];
    }
}
