<?php
declare(strict_types=1);

require dirname(__DIR__) . '/app/bootstrap.php';

use App\Repositories\OperationsRepository;
use App\Services\FairYearComparisonPolicy;

$hospital = strtolower((string)($argv[1] ?? 'njch'));
$year = (int)($argv[2] ?? date('Y'));
$compareYear = (int)($argv[3] ?? ($year - 1));

$contract = (new FairYearComparisonPolicy())->resolve($year, $compareYear);
$currentFrom = (string)($contract['from_date'] ?? sprintf('%04d-01-01', $year));
$currentTo = (string)($contract['to_date'] ?? sprintf('%04d-12-31', $year));
$compareFrom = OperationsRepository::shiftDateToYear($currentFrom, $compareYear);
$compareTo = OperationsRepository::shiftDateToYear($currentTo, $compareYear);

$repo = new OperationsRepository($hospital);
$currentSpecialties = $repo->topSpecialties($year, $currentFrom, $currentTo, 25);
$compareSpecialties = $repo->topSpecialties($compareYear, $compareFrom, $compareTo, 25);
$currentDoctors = $repo->topDoctors($year, $currentFrom, $currentTo, 25);
$compareDoctors = $repo->topDoctors($compareYear, $compareFrom, $compareTo, 25);

function mergeRows(array $currentRows, array $compareRows): array
{
    $merged = [];
    foreach ($compareRows as $row) {
        $label = trim((string)($row['label'] ?? ''));
        if ($label === '') continue;
        $key = mb_strtolower($label);
        $merged[$key] = [
            'label' => $label,
            'current_value' => 0.0,
            'compare_value' => (float)($row['value'] ?? 0),
        ];
    }
    foreach ($currentRows as $row) {
        $label = trim((string)($row['label'] ?? ''));
        if ($label === '') continue;
        $key = mb_strtolower($label);
        if (!isset($merged[$key])) {
            $merged[$key] = [
                'label' => $label,
                'current_value' => 0.0,
                'compare_value' => 0.0,
            ];
        }
        $merged[$key]['label'] = $label;
        $merged[$key]['current_value'] = (float)($row['value'] ?? 0);
    }

    $rows = array_values($merged);
    foreach ($rows as &$row) {
        $row['volume_change'] = (float)$row['current_value'] - (float)$row['compare_value'];
        $row['zero_current_loss'] = (float)$row['current_value'] <= 0.000001
            && (float)$row['compare_value'] > 0.000001;
    }
    unset($row);

    usort($rows, static function (array $a, array $b): int {
        $currentOrder = ((float)$b['current_value']) <=> ((float)$a['current_value']);
        if ($currentOrder !== 0) return $currentOrder;
        return ((float)$b['compare_value']) <=> ((float)$a['compare_value']);
    });
    return $rows;
}

function leaders(array $rows): array
{
    return array_slice(array_values(array_filter($rows, static function (array $row): bool {
        return (float)$row['current_value'] > 0.000001;
    })), 0, 5);
}

function descendingCurrent(array $rows): bool
{
    $previous = INF;
    foreach ($rows as $row) {
        $current = (float)$row['current_value'];
        if ($current > $previous + 0.000001) return false;
        $previous = $current;
    }
    return true;
}

$specialtyMerged = mergeRows($currentSpecialties, $compareSpecialties);
$doctorMerged = mergeRows($currentDoctors, $compareDoctors);
$specialtyLeaders = leaders($specialtyMerged);
$doctorLeaders = leaders($doctorMerged);
$zeroCurrentLosses = array_values(array_filter(
    array_merge($doctorMerged, $specialtyMerged),
    static function (array $row): bool { return !empty($row['zero_current_loss']); }
));

$checks = [
    'fair_period' => !empty($contract['fair_current_year_comparison']),
    'specialty_leaders_present' => count($specialtyLeaders) > 0,
    'doctor_leaders_present' => count($doctorLeaders) > 0,
    'specialty_leaders_current_positive' => count(array_filter($specialtyLeaders, static function (array $row): bool {
        return (float)$row['current_value'] <= 0.000001;
    })) === 0,
    'doctor_leaders_current_positive' => count(array_filter($doctorLeaders, static function (array $row): bool {
        return (float)$row['current_value'] <= 0.000001;
    })) === 0,
    'specialty_current_descending' => descendingCurrent($specialtyLeaders),
    'doctor_current_descending' => descendingCurrent($doctorLeaders),
    'zero_current_rows_not_in_doctor_leaders' => count(array_filter($doctorLeaders, static function (array $row): bool {
        return !empty($row['zero_current_loss']);
    })) === 0,
];

$failed = [];
foreach ($checks as $name => $pass) {
    if (!$pass) $failed[] = $name;
}

$result = [
    'schema' => 'DDB_OPERATIONS_R45_P9_1_LIVE_ACCEPTANCE_V1',
    'captured_at' => date(DATE_ATOM),
    'hospital' => $hospital,
    'periods' => [
        'current_from' => $currentFrom,
        'current_to' => $currentTo,
        'compare_from' => $compareFrom,
        'compare_to' => $compareTo,
    ],
    'leaders' => [
        'specialties' => $specialtyLeaders,
        'doctors' => $doctorLeaders,
    ],
    'zero_current_loss_count' => count($zeroCurrentLosses),
    'checks' => $checks,
    'status' => count($failed) === 0 ? 'PASS' : 'FAIL',
    'failed' => $failed,
    'oracle_writes' => 'NONE',
];

$dir = dirname(__DIR__) . '/storage/evidence/operations';
if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
    throw new RuntimeException('Cannot create Operations evidence directory.');
}
$file = $dir . '/OPERATIONS_R45_P9_1_LIVE_ACCEPTANCE_' . date('Ymd_His') . '.json';
file_put_contents($file, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), LOCK_EX);

echo json_encode($result + ['evidence_file' => $file], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES), PHP_EOL;
exit(count($failed) === 0 ? 0 : 1);
