<?php

namespace App\Http\Controllers\Ranch;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreWeightRecordRequest;
use App\Models\Cattle;
use App\Models\WeightRecord;
use App\Services\WeightRecordService;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use InvalidArgumentException;

class WeightRecordController extends Controller
{
    public function __construct(
        private readonly WeightRecordService $weightRecordService,
    ) {}

    public function index(Request $request): JsonResponse
    {
        $perPage = min(100, max(1, (int) $request->get('per_page', 20)));

        $query = WeightRecord::query()
            ->with(['cattle:id,ear_tag,breed', 'user:id,name'])
            ->orderByDesc('weighed_at');

        if ($request->filled('cattle_id')) {
            $query->where('cattle_id', $request->integer('cattle_id'));
        }

        return response()->json(['data' => $query->paginate($perPage)]);
    }

    public function calves(Request $request): JsonResponse
    {
        $maxMonths = (int) $request->get('max_age_months', config('ranch.calf.max_age_months', 12));
        $cutoff = Carbon::today()->subMonths(max(1, $maxMonths));

        $calves = Cattle::query()
            ->active()
            ->whereNotNull('mother_id')
            ->where(function ($query) use ($cutoff) {
                $query->whereNull('birth_date')
                    ->orWhereDate('birth_date', '>=', $cutoff);
            })
            ->with([
                'mother:id,ear_tag',
                'weightRecords' => fn ($q) => $q->orderByDesc('weighed_at')->limit(1),
            ])
            ->orderByDesc('birth_date')
            ->orderByDesc('id')
            ->limit(150)
            ->get()
            ->map(fn (Cattle $cattle) => [
                'id' => $cattle->id,
                'ear_tag' => $cattle->ear_tag,
                'display_ear_tag' => $cattle->display_ear_tag,
                'gender' => $cattle->gender,
                'birth_date' => $cattle->birth_date?->toDateString(),
                'age_months' => $cattle->birth_date
                    ? (int) $cattle->birth_date->diffInMonths(Carbon::today())
                    : null,
                'mother' => $cattle->mother ? [
                    'id' => $cattle->mother->id,
                    'ear_tag' => $cattle->mother->ear_tag,
                ] : null,
                'pasture_location' => $cattle->pasture_location,
                'last_weight' => ($last = $cattle->weightRecords->first()) ? [
                    'weight_kg' => $last->weight_kg,
                    'weighed_at' => $last->weighed_at->toDateString(),
                    'daily_weight_gain' => $last->daily_weight_gain,
                ] : null,
            ])
            ->values();

        return response()->json(['data' => $calves]);
    }

    public function store(StoreWeightRecordRequest $request): JsonResponse
    {
        $cattle = $request->filled('cattle_id')
            ? Cattle::findOrFail($request->integer('cattle_id'))
            : Cattle::where('ear_tag', $request->string('ear_tag'))->first();

        if (! $cattle) {
            return response()->json(['message' => 'Animal no encontrado.'], 404);
        }

        if (! $cattle->isActive()) {
            return response()->json(['message' => 'El animal no está activo.'], 422);
        }

        $record = $this->weightRecordService->record(
            $cattle,
            (float) $request->input('weight_kg'),
            Carbon::parse($request->input('weighed_at')),
            $request->input('notes'),
            (int) auth()->id()
        );

        return response()->json(['data' => $record->load('cattle:id,ear_tag')], 201);
    }
}
