<?php

namespace App\Http\Controllers\Ranch;

use App\Http\Controllers\Controller;
use App\Http\Requests\StoreCattleHealthEventRequest;
use App\Models\CattleHealthEvent;
use App\Models\FatteningLotAnimal;
use App\Models\MaterialType;
use App\Services\CattleHealthEventService;
use App\Services\RanchHealthReportService;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use InvalidArgumentException;

class CattleHealthEventController extends Controller
{
    public function __construct(
        private readonly CattleHealthEventService $healthEventService,
        private readonly RanchHealthReportService $healthReportService,
    ) {}

    public function catalog(): JsonResponse
    {
        return response()->json([
            'data' => [
                'event_types' => config('ranch.health_event_types'),
                'outcomes' => config('ranch.health_outcomes'),
                'auto_material_expense' => config('ranch.health.auto_material_expense', true),
                'material_types' => MaterialType::query()
                    ->active()
                    ->where('category', config('ranch.health.material_category', 'animal_health'))
                    ->orderBy('name')
                    ->get(['id', 'name', 'unit', 'category']),
            ],
        ]);
    }

    public function index(Request $request): JsonResponse
    {
        $perPage = min(100, max(1, (int) $request->get('per_page', 25)));
        $query = CattleHealthEvent::query()
            ->with([
                'cattle:id,ear_tag,status',
                'materialType:id,name,unit',
                'materialExpense:id,total_cost,quantity,unit_cost,expense_date,material_type_id',
                'user:id,name',
            ])
            ->orderByDesc('event_date');

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

        if ($request->filled('event_type')) {
            $query->where('event_type', $request->string('event_type'));
        }

        if ($request->filled('fattening_lot_id')) {
            $cattleIds = FatteningLotAnimal::query()
                ->where('fattening_lot_id', $request->integer('fattening_lot_id'))
                ->pluck('cattle_id');
            $query->whereIn('cattle_id', $cattleIds);
        }

        if ($request->filled('from') && $request->filled('to')) {
            $query->whereBetween('event_date', [
                $request->date('from')->toDateString(),
                $request->date('to')->toDateString(),
            ]);
        }

        if ($earTag = trim((string) $request->get('ear_tag', ''))) {
            $query->whereHas('cattle', fn ($q) => $q->where('ear_tag', 'like', '%'.$earTag.'%'));
        }

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

    public function store(StoreCattleHealthEventRequest $request): JsonResponse
    {
        try {
            $event = $this->healthEventService->record(
                $request->validated(),
                (int) auth()->id()
            );
        } catch (InvalidArgumentException $e) {
            return response()->json(['message' => $e->getMessage()], 422);
        }

        return response()->json(['data' => $event], 201);
    }

    public function summary(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'from' => ['nullable', 'date'],
            'to' => ['nullable', 'date', 'after_or_equal:from'],
        ]);

        $from = isset($validated['from']) ? Carbon::parse($validated['from']) : null;
        $to = isset($validated['to']) ? Carbon::parse($validated['to']) : null;

        return response()->json([
            'data' => $this->healthReportService->summary($from, $to),
        ]);
    }
}
