<?php

namespace App\Services;

use App\Models\Project;
use App\Models\ProjectMonthPlan;
use Illuminate\Support\Collection;

class ReconciliationCalculator
{
    /**
     * Calculate reconciliation status for a single project.
     * Returns OVER, UNDER, or MATCH based on plan_sum vs approved_estimate.
     */
    public function calculateStatus(Project $project, ?Collection $plans = null): string
    {
        $approved = (float) $project->approved_estimate;

        // If no approved estimate, consider it UNDER
        if ($approved <= 0) {
            return 'UNDER';
        }

        $planSum = $this->calculatePlanSum($project, $plans);

        // Use decimal-safe comparison
        if ($this->isGreaterThan($planSum, $approved)) {
            return 'OVER';
        }

        if ($this->isLessThan($planSum, $approved)) {
            return 'UNDER';
        }

        return 'MATCH';
    }

    /**
     * Calculate the sum of planned hours for a project.
     * Only sums non-null planned_hours values.
     */
    public function calculatePlanSum(Project $project, ?Collection $plans = null): float
    {
        if ($plans === null) {
            $plans = ProjectMonthPlan::where('project_id', $project->id)->get();
        }

        return $plans
            ->filter(fn ($plan) => $plan->planned_hours !== null)
            ->sum('planned_hours');
    }

    /**
     * Calculate plan sum and status for multiple projects.
     * Returns array with project_id => ['plan_sum' => float, 'status' => string].
     */
    public function calculateForProjects(Collection $projects, int $year): array
    {
        $startDate = "{$year}-01-01";
        $endDate = "{$year}-12-01";

        // Get all plans for the year, grouped by project_id
        $allPlans = ProjectMonthPlan::whereBetween('month', [$startDate, $endDate])
            ->get()
            ->groupBy('project_id');

        $results = [];

        foreach ($projects as $project) {
            $projectPlans = $allPlans->get($project->id, collect());
            $planSum = $this->calculatePlanSum($project, $projectPlans);
            $status = $this->calculateStatus($project, $projectPlans);

            $results[$project->id] = [
                'plan_sum' => $planSum,
                'status' => $status,
                'approved_estimate' => $project->approved_estimate,
            ];
        }

        return $results;
    }

    /**
     * Compare two floats using epsilon for decimal-safe comparison.
     */
    private function isGreaterThan(float $a, float $b): bool
    {
        $epsilon = 0.0001;

        return ($a - $b) > $epsilon;
    }

    /**
     * Compare two floats using epsilon for decimal-safe comparison.
     */
    private function isLessThan(float $a, float $b): bool
    {
        $epsilon = 0.0001;

        return ($b - $a) > $epsilon;
    }
}
