<?php

namespace App\Services;

use App\Models\Cattle;
use App\Models\CattleHealthEvent;
use App\Models\WeightRecord;

class RanchMotherPerformanceService
{
    /**
     * Vacas con crías: peso promedio, GDP promedio y tasa de mortalidad de la progenie.
     *
     * @return array{
     *   mothers_count: int,
     *   high_mortality_threshold_pct: float,
     *   mothers: list<array<string, mixed>>
     * }
     */
    public function generate(?float $highMortalityThresholdPct = null): array
    {
        $threshold = $highMortalityThresholdPct ?? (float) config('ranch.mother_performance.high_mortality_threshold_pct', 25);
        $illnessThreshold = (int) config('ranch.health_alerts.offspring_illness_threshold', 2);

        $mothers = Cattle::query()
            ->where('gender', 'female')
            ->whereHas('offspring')
            ->with(['offspring' => fn ($q) => $q->orderBy('ear_tag')])
            ->orderBy('ear_tag')
            ->get();

        $rows = [];

        foreach ($mothers as $mother) {
            $offspring = $mother->offspring;
            $total = $offspring->count();
            $dead = $offspring->where('status', Cattle::STATUS_DEAD)->count();
            $active = $offspring->where('status', Cattle::STATUS_ACTIVE)->count();

            $weights = [];
            $gdps = [];

            foreach ($offspring as $child) {
                $latest = WeightRecord::query()
                    ->where('cattle_id', $child->id)
                    ->orderByDesc('weighed_at')
                    ->first();

                $weight = $child->exit_weight_kg ?? $latest?->weight_kg;
                if ($weight !== null) {
                    $weights[] = (float) $weight;
                }

                if ($latest?->daily_weight_gain !== null) {
                    $gdps[] = (float) $latest->daily_weight_gain;
                }
            }

            $mortalityPct = $total > 0 ? round(($dead / $total) * 100, 1) : 0.0;
            $avgWeight = count($weights) > 0 ? round(array_sum($weights) / count($weights), 2) : null;
            $avgGdp = count($gdps) > 0 ? round(array_sum($gdps) / count($gdps), 4) : null;

            $offspringIllness = CattleHealthEvent::query()
                ->whereIn('cattle_id', $offspring->pluck('id'))
                ->where('event_type', CattleHealthEvent::TYPE_ILLNESS)
                ->count();

            $rows[] = [
                'mother_id' => $mother->id,
                'ear_tag' => $mother->ear_tag,
                'breed' => $mother->breed,
                'status' => $mother->status,
                'offspring_count' => $total,
                'offspring_active' => $active,
                'offspring_dead' => $dead,
                'offspring_sold' => $offspring->where('status', Cattle::STATUS_SOLD)->count(),
                'mortality_rate_pct' => $mortalityPct,
                'avg_offspring_weight_kg' => $avgWeight,
                'avg_offspring_gdp' => $avgGdp,
                'offspring_illness_events' => $offspringIllness,
                'high_mortality_risk' => $mortalityPct >= $threshold && $dead > 0,
                'health_risk' => $offspringIllness >= $illnessThreshold,
                'top_producer' => false,
            ];
        }

        usort($rows, function ($a, $b) {
            $wA = $a['avg_offspring_weight_kg'] ?? 0;
            $wB = $b['avg_offspring_weight_kg'] ?? 0;

            return $wB <=> $wA;
        });

        $maxWeight = $rows[0]['avg_offspring_weight_kg'] ?? null;
        if ($maxWeight !== null) {
            foreach ($rows as &$row) {
                if ($row['avg_offspring_weight_kg'] !== null && $row['avg_offspring_weight_kg'] >= $maxWeight) {
                    $row['top_producer'] = true;
                }
            }
            unset($row);
        }

        return [
            'mothers_count' => count($rows),
            'high_mortality_threshold_pct' => $threshold,
            'mothers' => $rows,
        ];
    }
}
