<?php

namespace App\Http\Controllers;

use App\Models\Note;
use App\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class NotesRemindersController extends Controller
{
    private const NOTE_COLORS = ['yellow', 'blue', 'green', 'pink', 'purple', 'orange', 'red', 'teal', 'indigo', 'cyan', 'lime', 'gray'];

    private const TASK_STATUSES = ['later', 'in_progress', 'done'];

    private const TASK_PRIORITIES = ['high', 'medium', 'low'];

    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index(Request $request)
    {
        $userId = Auth::id();
        $noteQuery = trim((string) $request->query('note_q', ''));
        $taskQuery = trim((string) $request->query('task_q', ''));

        $notes = Note::query()
            ->where('user_id', $userId)
            ->when($noteQuery !== '', function ($q) use ($noteQuery) {
                $q->where(function ($q) use ($noteQuery) {
                    $q->where('title', 'like', '%'.$noteQuery.'%')
                        ->orWhere('content', 'like', '%'.$noteQuery.'%');
                });
            })
            ->orderByDesc('is_pinned')
            ->orderByDesc('id')
            ->get();

        $tasksAll = Task::query()
            ->where('user_id', $userId)
            ->when($taskQuery !== '', function ($q) use ($taskQuery) {
                $q->where(function ($q) use ($taskQuery) {
                    $q->where('title', 'like', '%'.$taskQuery.'%')
                        ->orWhere('description', 'like', '%'.$taskQuery.'%');
                });
            })
            ->orderByRaw("CASE status WHEN 'in_progress' THEN 1 WHEN 'later' THEN 2 WHEN 'done' THEN 3 ELSE 4 END")
            ->orderByRaw("CASE priority WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END")
            ->orderBy('due_date')
            ->orderByDesc('id')
            ->get();

        $tasksByStatus = [
            'later' => $tasksAll->where('status', 'later')->values(),
            'in_progress' => $tasksAll->where('status', 'in_progress')->values(),
            'done' => $tasksAll->where('status', 'done')->values(),
        ];

        $browserReminderTasks = Task::query()
            ->where('user_id', $userId)
            ->whereNotNull('reminder_at')
            ->where('reminder_at', '<=', now())
            ->where('status', '!=', 'done')
            ->orderBy('reminder_at')
            ->limit(10)
            ->get();

        $tasksForBrowserNotifications = $browserReminderTasks
            ->map(fn (Task $task) => [
                'id' => $task->id,
                'title' => $task->title,
                'reminder_at' => $task->reminder_at?->toIso8601String(),
            ])
            ->values()
            ->all();

        return view('system_assistant.notes_reminders', [
            'noteQuery' => $noteQuery,
            'taskQuery' => $taskQuery,
            'notes' => $notes,
            'tasksByStatus' => $tasksByStatus,
            'tasksForBrowserNotifications' => $tasksForBrowserNotifications,
            'noteColors' => self::NOTE_COLORS,
        ]);
    }

    public function storeNote(Request $request)
    {
        $data = $request->validate([
            'title' => ['nullable', 'string', 'max:255'],
            'content' => ['required', 'string', 'max:5000'],
            'color' => ['required', 'string', 'in:'.implode(',', self::NOTE_COLORS)],
            'is_pinned' => ['nullable', 'boolean'],
        ]);

        Note::query()->create([
            'user_id' => Auth::id(),
            'title' => $data['title'] ?? null,
            'content' => $data['content'],
            'color' => $data['color'],
            'is_pinned' => (bool) ($data['is_pinned'] ?? false),
        ]);

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.notes.saved'));
    }

    public function updateNote(Request $request, int $id)
    {
        $note = Note::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('update', $note);

        $data = $request->validate([
            'title' => ['nullable', 'string', 'max:255'],
            'content' => ['required', 'string', 'max:5000'],
            'color' => ['required', 'string', 'in:'.implode(',', self::NOTE_COLORS)],
            'is_pinned' => ['nullable', 'boolean'],
        ]);

        $note->update([
            'title' => $data['title'] ?? null,
            'content' => $data['content'],
            'color' => $data['color'],
            'is_pinned' => (bool) ($data['is_pinned'] ?? false),
        ]);

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.notes.updated'));
    }

    public function destroyNote(int $id)
    {
        $note = Note::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('delete', $note);

        $note->delete();

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.notes.deleted'));
    }

    public function togglePinNote(int $id)
    {
        $note = Note::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('update', $note);

        $note->update(['is_pinned' => ! $note->is_pinned]);

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.notes.updated'));
    }

    public function convertNoteToTask(int $id)
    {
        $note = Note::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('view', $note);

        $title = trim((string) ($note->title ?: mb_substr($note->content, 0, 60)));
        if ($title === '') {
            $title = __('notes_reminders.tasks.new_task');
        }

        Task::query()->create([
            'user_id' => Auth::id(),
            'title' => $title,
            'description' => $note->content,
            'status' => 'later',
            'priority' => 'medium',
            'due_date' => null,
            'reminder_at' => null,
        ]);

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.tasks.saved'));
    }

    public function storeTask(Request $request)
    {
        $data = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string', 'max:5000'],
            'priority' => ['required', 'string', 'in:'.implode(',', self::TASK_PRIORITIES)],
            'due_date' => ['nullable', 'date'],
            'reminder_at' => ['nullable', 'date'],
        ]);

        Task::query()->create([
            'user_id' => Auth::id(),
            'title' => $data['title'],
            'description' => $data['description'] ?? null,
            'status' => 'later',
            'priority' => $data['priority'],
            'due_date' => $data['due_date'] ?? null,
            'reminder_at' => $data['reminder_at'] ?? null,
        ]);

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.tasks.saved'));
    }

    public function updateTask(Request $request, int $id)
    {
        $task = Task::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('update', $task);

        $data = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string', 'max:5000'],
            'status' => ['required', 'string', 'in:'.implode(',', self::TASK_STATUSES)],
            'priority' => ['required', 'string', 'in:'.implode(',', self::TASK_PRIORITIES)],
            'due_date' => ['nullable', 'date'],
            'reminder_at' => ['nullable', 'date'],
        ]);

        $task->update($data);

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.tasks.updated'));
    }

    public function destroyTask(int $id)
    {
        $task = Task::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('delete', $task);

        $task->delete();

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.tasks.deleted'));
    }

    public function updateTaskStatus(Request $request, int $id)
    {
        $task = Task::query()
            ->where('id', $id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        $this->authorize('update', $task);

        $data = $request->validate([
            'status' => ['required', 'string', 'in:'.implode(',', self::TASK_STATUSES)],
        ]);

        $task->update(['status' => $data['status']]);

        if ($request->expectsJson()) {
            return response()->json(['ok' => true]);
        }

        return redirect()
            ->route('system-assistant.notes-reminders')
            ->with('success', __('notes_reminders.tasks.updated'));
    }
}
