<?php
 
function calculateMonthlyPayroll(PDO $pdo, string $employeeId, int $year, int $month): float
{
    if ($month < 1 || $month > 12) {
        throw new InvalidArgumentException('Month must be between 1 and 12');
    }
 
    // Get all active contracts for the employee in this month
    $contracts = getActiveContracts($pdo, $employeeId, $year, $month);
 
    $totalAmount = 0.0;
 
    // Calculate previous month for revenue share considerations
    $previousMonth = $month - 1;
    $previousYear = $year;
    if ($previousMonth < 1) {
        $previousMonth = 12;
        $previousYear = $year - 1;
    }
 
    // Process each contract based on role
    foreach ($contracts as $contract) {
        $roleCategory = $contract['role_category'];
 
        switch ($roleCategory) {
            case 'actor':
                // Fixed fee installment
                if ($contract['fixed_fee_total'] && $contract['filming_duration_months']) {
                    $totalAmount += $contract['fixed_fee_total'] / $contract['filming_duration_months'];
                }
 
                // Calculate revenue share for the previous month
                if ($contract['revenue_share_percentage']) {
                    $revenue = getFilmRevenue($pdo, $contract['film_id'], $previousYear, $previousMonth);
                    if ($revenue) {
                        $totalAmount += $revenue * ($contract['revenue_share_percentage'] / 100);
                    }
                }
                break;
 
            case 'production_staff':
                // Production Staff: Monthly fixed amount only
                if ($contract['monthly_amount']) {
                    $totalAmount += $contract['monthly_amount'];
                }
                break;
 
            case 'senior_staff':
                // Monthly fixed amount
                if ($contract['monthly_amount']) {
                    $totalAmount += $contract['monthly_amount'];
                }
 
                // Ongoing revenue share from PREVIOUS month
                if ($contract['revenue_share_percentage']) {
                    $revenue = getFilmRevenue($pdo, $contract['film_id'], $previousYear, $previousMonth);
                    if ($revenue) {
                        $totalAmount += $revenue * ($contract['revenue_share_percentage'] / 100);
                    }
                }
                break;
        }
    }
 
    return $totalAmount;
}
 
// Get active contracts for an employee in a specific month.
function getActiveContracts
(PDO 
$pdo, string 
$employeeId, int 
$year, int 
$month): array {   
    // Calculate the first day of the month for contract validity check
    $calculationDate = sprintf('%04d-%02d-01', $year, $month);  
    $stmt = $pdo->prepare("
        SELECT 
            c.id,
            c.fixed_fee_total,
            c.monthly_amount,
            c.filming_duration_months,
            c.revenue_share_percentage,
            r.category as role_category,
            f.id as film_id
        FROM contract c
        INNER JOIN role r ON c.role_id = r.id
        INNER JOIN film f ON c.film_id = f.id
        WHERE c.employee_id = :employee_id
          AND c.start_date <= :calculation_date
          AND c.end_date >= :calculation_date
          AND c.status = 'active'
    ");
 
    $stmt->execute([
        'employee_id' => $employeeId,
        'calculation_date' => $calculationDate
    ]);
 
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
 
// Get film revenue for a specific month.
function getFilmRevenue(PDO $pdo, string $filmId, int $year, int $month): ?float
{
    $stmt = $pdo->prepare("
        SELECT revenue_amount
        FROM film_revenue
        WHERE film_id = :film_id
          AND year = :year
          AND month = :month
    ");
 
    $stmt->execute([
        'film_id' => $filmId,
        'year' => $year,
        'month' => $month
    ]);
 
    $result = $stmt->fetch(PDO::FETCH_ASSOC);
    return $result ? (float) $result['revenue_amount'] : null;
}