<?php

namespace App\Http\Controllers;

use App\Http\Requests\AssignPlantsRequest;
use App\Models\GrapeVariety;
use App\Models\VarietyVariation;
use App\Models\VineyardRow;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use RuntimeException;

class PlantController extends Controller
{
    /**
     * Display the add-plants workflow.
     */
    public function showAddForm(Request $request)
    {
        $rowsInput = $request->input('rows', []);

        if (is_string($rowsInput)) {
            $rowsInput = array_filter(array_map('trim', explode(',', $rowsInput)));
        }

        $selectedRowIds = collect($rowsInput)
            ->map(fn ($value) => (int) $value)
            ->filter()
            ->values();

        $rows = VineyardRow::with('varietyVariation.grapeVariety')
            ->when($selectedRowIds->isNotEmpty(), fn ($query) => $query->whereIn('id', $selectedRowIds))
            ->orderBy('id')
            ->get();

        $variations = VarietyVariation::with('grapeVariety')
            ->orderBy('grape_variety_id')
            ->get()
            ->map(fn (VarietyVariation $variation) => [
                'id' => $variation->getKey(),
                'label' => sprintf('%s — %s', $variation->grapeVariety->variety_name, ucfirst($variation->color)),
            ]);

        return view('vineyard.plants.add', [
            'rows' => $rows,
            'variationOptions' => $variations,
            'selectedRowIds' => $selectedRowIds,
        ]);
    }

    /**
     * Assign a variation to selected rows, creating plants in bulk.
     */
    public function assignToRows(AssignPlantsRequest $request)
    {
        $rows = VineyardRow::whereIn('id', $request->validated('rows'))->get();

        if ($rows->isEmpty()) {
            return response()->json([
                'success' => false,
                'message' => 'No matching rows were found for assignment.',
            ], 422);
        }

        $variationId = $this->resolveVariationId($request);

        DB::transaction(function () use ($rows, $variationId) {
            foreach ($rows as $row) {
                $row->update([
                    'variety_variation_id' => $variationId,
                    'planting_year' => now()->year,
                    'status' => 'active',
                ]);
            }
        });

        return response()->json([
            'success' => true,
            'updated_rows' => $rows->pluck('id'),
        ]);
    }

    protected function resolveVariationId(AssignPlantsRequest $request): int
    {
        $variationId = $request->validated('variety_variation_id');

        if ($variationId) {
            return (int) $variationId;
        }

        $payload = $request->validated('create_variation');

        if (! $payload) {
            throw new RuntimeException('A variety variation must be provided or created for assignment.');
        }

        $variety = null;

        if (! empty($payload['grape_variety_id'])) {
            $variety = GrapeVariety::find($payload['grape_variety_id']);
        }

        if (! $variety && ! empty($payload['grape_variety_name'])) {
            $variety = GrapeVariety::firstOrCreate([
                'variety_name' => $payload['grape_variety_name'],
            ]);
        }

        if (! $variety) {
            throw new RuntimeException('Unable to resolve grape variety for the new variation.');
        }

        $variation = VarietyVariation::firstOrCreate(
            [
                'grape_variety_id' => $variety->getKey(),
                'color' => $payload['color'],
            ],
            [
                'description' => $payload['description'] ?? null,
                'typical_sugar_content' => $payload['typical_sugar_content'] ?? null,
                'typical_alcohol' => $payload['typical_alcohol'] ?? null,
                'ripening_period' => $payload['ripening_period'] ?? null,
                'status' => 'active',
            ]
        );

        return $variation->getKey();
    }
}
