<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreBulkPlannedTasksRequest;
use App\Http\Requests\UpdatePlannedTaskRequest;
use App\Models\PlannedTask;
use App\Models\Treatment;
use App\Models\VineyardRow;
use App\Services\BulkPlannedTaskService;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;

class PlannedTaskController extends Controller
{
    public function __construct(protected BulkPlannedTaskService $bulkService)
    {
    }

    public function showWateringForm(Request $request)
    {
        if (! $request->query('date')) {
            return redirect()->route('vineyard.map')
                ->with('error', 'Please choose a date on the vineyard map before planning watering.');
        }

        return $this->renderForm('watering', 'planned-tasks.watering', $request);
    }

    public function showPruningForm(Request $request)
    {
        if (! $request->query('date')) {
            return redirect()->route('vineyard.map')
                ->with('error', 'Please choose a date on the vineyard map before planning pruning.');
        }

        return $this->renderForm('pruning', 'planned-tasks.pruning', $request);
    }

    public function showFertilisationForm(Request $request)
    {
        if (! $request->query('date')) {
            return redirect()->route('vineyard.map')
                ->with('error', 'Please choose a date on the vineyard map before planning fertilisation.');
        }

        return $this->renderForm('fertilization', 'planned-tasks.fertilisation', $request, 'fertilisation');
    }

    public function showPesticideForm(Request $request)
    {
        if (! $request->query('date')) {
            return redirect()->route('vineyard.map')
                ->with('error', 'Please choose a date on the vineyard map before planning pesticide treatment.');
        }

        return $this->renderForm('spraying', 'planned-tasks.pesticide', $request, 'pesticide');
    }

    public function showHarvestForm(Request $request)
    {
        if (! $request->query('date')) {
            return redirect()->route('vineyard.map')
                ->with('error', 'Please choose a date on the vineyard map before planning harvest.');
        }

        return $this->renderForm('harvest', 'planned-tasks.harvest', $request);
    }

    public function storeBulk(StoreBulkPlannedTasksRequest $request)
    {
        $result = $this->bulkService->handle($request->validated());

        $status = $result['success'] ? 201 : 422;

        return response()->json($result, $status);
    }

    protected function renderForm(string $actionKey, string $view, Request $request, ?string $displayAction = null)
    {
        $selectedRowIds = $this->parseRowIds($request->input('rows', []));

        $plannedDate = $request->query('date');

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

        return view($view, [
            'action' => $displayAction ?? $actionKey,
            'actionKey' => $actionKey,
            'rows' => $rows,
            'selectedRowIds' => $selectedRowIds,
            'plannedDate' => $plannedDate,
        ]);
    }

    protected function parseRowIds(array|string $value): Collection
    {
        if (is_string($value)) {
            $value = explode(',', $value);
        }

        return collect($value)
            ->map(fn ($id) => (int) $id)
            ->filter(fn ($id) => $id > 0)
            ->values();
    }

    public function edit(PlannedTask $task)
    {
        $task->load('taskable');

        // Find all tasks in the same group (same type, date, note)
        $groupTasks = PlannedTask::with('taskable')
            ->where('type', $task->type)
            ->where('planned_date', $task->planned_date)
            ->where(function($query) use ($task) {
                if ($task->note) {
                    $query->where('note', $task->note);
                } else {
                    $query->whereNull('note');
                }
            })
            ->whereNull('execution_date')
            ->get();

        // Build task_rows array with task IDs and vineyard row info
        $taskRows = $groupTasks->map(function($t) {
            $row = null;

            if (!$t->taskable) {
                return null;
            }

            // Check taskable type to determine how to get vineyard row
            $taskableType = $t->taskable_type;

            // For Harvest, vineyard_row_id is directly on the taskable
            if (str_contains($taskableType, 'Harvest') && $t->taskable->vineyard_row_id) {
                $row = VineyardRow::with('varietyVariation.grapeVariety')
                    ->find($t->taskable->vineyard_row_id);
            }
            // For treatment types (Watering, Spraying, Fertilization, Pruning), get it through parent Treatment
            elseif ($t->taskable->treatment_id) {
                $treatment = Treatment::with('vineyardRow.varietyVariation.grapeVariety')
                    ->find($t->taskable->treatment_id);
                if ($treatment && $treatment->vineyardRow) {
                    $row = $treatment->vineyardRow;
                }
            }

            return $row ? [
                'task_id' => $t->planned_task_id,
                'row_id' => $row->id,
                'row' => $row,
            ] : null;
        })->filter()->sortBy('row_id')->values();

        // Get the vineyard row for the main task (for display)
        $vineyardRow = null;
        if ($task->taskable) {
            $taskableType = $task->taskable_type;

            // For Harvest
            if (str_contains($taskableType, 'Harvest') && $task->taskable->vineyard_row_id) {
                $vineyardRow = VineyardRow::with('varietyVariation.grapeVariety')
                    ->find($task->taskable->vineyard_row_id);
            }
            // For treatment types
            elseif ($task->taskable->treatment_id) {
                $treatment = Treatment::with('vineyardRow.varietyVariation.grapeVariety')
                    ->find($task->taskable->treatment_id);
                if ($treatment) {
                    $vineyardRow = $treatment->vineyardRow;
                }
            }
        }

        return view('planned-tasks.edit', [
            'task' => $task,
            'vineyardRow' => $vineyardRow,
            'taskRows' => $taskRows,
        ]);
    }

    public function update(UpdatePlannedTaskRequest $request, PlannedTask $task)
    {
        $validated = $request->validated();

        // Get selected task IDs (if provided, otherwise just update the single task)
        $taskIds = $request->input('task_ids', [$task->planned_task_id]);

        // Get all selected tasks
        $tasksToUpdate = PlannedTask::with('taskable')
            ->whereIn('planned_task_id', $taskIds)
            ->whereNull('execution_date')
            ->get();

        foreach ($tasksToUpdate as $taskToUpdate) {
            // Update PlannedTask
            $updateData = [
                'note' => $validated['note'] ?? null,
            ];

            // For spraying and harvest tasks, don't update the date (it's readonly)
            if (!str_contains($taskToUpdate->taskable_type, 'Spraying') && !str_contains($taskToUpdate->taskable_type, 'Harvest') && isset($validated['planned_date'])) {
                $updateData['planned_date'] = $validated['planned_date'];
            }

            $taskToUpdate->update($updateData);

            // Update taskable (Treatment/Harvest) specific fields
            if ($taskToUpdate->taskable) {
                $taskableData = [];
                $taskableType = $taskToUpdate->taskable_type;

                if (str_contains($taskableType, 'Watering')) {
                    $taskableData = [
                        'time_interval' => $validated['time_interval'] ?? null,
                        'amount' => $validated['amount'],
                    ];
                } elseif (str_contains($taskableType, 'Fertilization')) {
                    $taskableData = [
                        'substance' => $validated['substance'],
                        'concentration' => $validated['concentration'] ?? null,
                    ];
                } elseif (str_contains($taskableType, 'Spraying')) {
                    $taskableData = [
                        'pesticide' => $validated['pesticide'],
                        'concentration' => $validated['concentration'] ?? null,
                    ];
                } elseif (str_contains($taskableType, 'Pruning')) {
                    $taskableData = [
                        'method' => $validated['method'],
                        'percentage_removed' => $validated['percentage_removed'] ?? null,
                    ];
                }

                if (!empty($taskableData)) {
                    $taskToUpdate->taskable->update($taskableData);
                }
            }
        }

        $count = $tasksToUpdate->count();
        $message = $count === 1
            ? 'Planned task updated successfully.'
            : "{$count} planned tasks updated successfully.";

        return redirect()->route('winemaker.planned-tasks')
            ->with('success', $message);
    }

    public function destroy(PlannedTask $task)
    {
        // Delete the taskable first (Treatment/Harvest)
        if ($task->taskable) {
            $task->taskable->delete();
        }

        // Delete the planned task
        $task->delete();

        return redirect()->route('winemaker.planned-tasks')
            ->with('success', 'Planned task deleted successfully.');
    }
}
