<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\BatchSplitEvents\StoreBatchSplitEventRequest;
use App\Models\Batch;
use App\Models\BatchSplitEvent;
use App\Support\BatchKpiSnapshotService;
use App\Support\BatchMetrics;
use Illuminate\Http\JsonResponse;

class BatchSplitEventController extends Controller
{
    public function index(): JsonResponse
    {
        $userId = (int) auth('api')->id();
        $events = BatchSplitEvent::query()
            ->with(['session', 'sourceBatch', 'destinationBatch'])
            ->where('user_id', $userId)
            ->orderByDesc('date')
            ->latest()
            ->get();

        return $this->success($events, 'Batch split events list');
    }

    public function store(StoreBatchSplitEventRequest $request): JsonResponse
    {
        $userId = (int) auth('api')->id();
        $payload = $request->validated();

        $sourceBatch = Batch::query()->where('user_id', $userId)->find((int) $payload['source_batch_id']);
        $destinationBatch = Batch::query()->where('user_id', $userId)->find((int) $payload['destination_batch_id']);

        if (! $sourceBatch || ! $destinationBatch) {
            return $this->error('Batch not found', null, 404);
        }

        if ((int) $sourceBatch->id === (int) $destinationBatch->id) {
            return $this->error('Source and destination batch must be different', null, 422);
        }

        if ((string) $sourceBatch->status !== 'active' || (string) $destinationBatch->status !== 'active') {
            return $this->error('Only active batches can be used in desdobles', null, 422);
        }

        $date = (string) $payload['date'];
        $fishMoved = max(0, (int) ($payload['fish_moved'] ?? 0));
        $fishMissing = max(0, (int) ($payload['fish_missing'] ?? 0));
        $avgWeightMovedG = max(0.0, (float) ($payload['avg_weight_moved_g'] ?? 0));

        $sourceFishAvailable = BatchMetrics::liveFishCountAtDate($sourceBatch, $date);
        if ($sourceFishAvailable < ($fishMoved + $fishMissing)) {
            return $this->error('Source batch does not have enough live fish for this desdoble', [
                'source_batch_id' => (int) $sourceBatch->id,
                'fish_available' => $sourceFishAvailable,
            ], 422);
        }

        $theoretical = $sourceFishAvailable;
        $counted = max(0, $theoretical - $fishMissing);

        $event = BatchSplitEvent::create([
            'user_id' => $userId,
            'source_batch_id' => (int) $sourceBatch->id,
            'destination_batch_id' => (int) $destinationBatch->id,
            'date' => $date,
            'fish_count_theoretical' => $theoretical,
            'fish_count_counted' => $counted,
            'fish_moved' => $fishMoved,
            'fish_missing' => $fishMissing,
            'avg_weight_moved_g' => $avgWeightMovedG,
            'biomass_moved_kg' => BatchMetrics::biomassKg($fishMoved, $avgWeightMovedG),
            'notes' => $payload['notes'] ?? null,
        ]);

        BatchMetrics::syncBatch($sourceBatch);
        BatchMetrics::syncBatch($destinationBatch);
        BatchKpiSnapshotService::syncMany([$sourceBatch, $destinationBatch], $date);

        return $this->success($event->load(['session', 'sourceBatch', 'destinationBatch']), 'Batch split event created', 201);
    }

    public function show(int $id): JsonResponse
    {
        $userId = (int) auth('api')->id();
        $event = BatchSplitEvent::query()
            ->with(['session', 'sourceBatch', 'destinationBatch'])
            ->where('user_id', $userId)
            ->find($id);

        if (! $event) {
            return $this->error('Batch split event not found', null, 404);
        }

        return $this->success($event, 'Batch split event details');
    }

    public function destroy(int $id): JsonResponse
    {
        $userId = (int) auth('api')->id();
        $event = BatchSplitEvent::query()->where('user_id', $userId)->find($id);

        if (! $event) {
            return $this->error('Batch split event not found', null, 404);
        }

        $sourceBatch = Batch::query()->where('user_id', $userId)->find((int) $event->source_batch_id);
        $destinationBatch = Batch::query()->where('user_id', $userId)->find((int) $event->destination_batch_id);

        $event->delete();

        if ($sourceBatch) {
            BatchMetrics::syncBatch($sourceBatch);
            BatchKpiSnapshotService::syncBatch($sourceBatch);
        }

        if ($destinationBatch) {
            BatchMetrics::syncBatch($destinationBatch);
            BatchKpiSnapshotService::syncBatch($destinationBatch);
        }

        return $this->success(null, 'Batch split event deleted');
    }
}
