<?php

namespace App\Http\Requests;

use App\Enums\TaskPriority;
use App\Enums\TaskStatus;
use App\Enums\TaskAccess;
use App\Models\Task;
use App\Support\IdFormatter;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class TaskUpdateRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }

    public function rules(): array
    {
        $user = $this->user();
        $taskId = $this->route('id');

        if ($taskId) {
            $binId = IdFormatter::hexToBinary($taskId);
            $task = $binId ? Task::find($binId) : null;
            if ($task
                && $user->id === $task->assigned_to
                && $user->id !== $task->created_by
                && !$user->hasRole('owner')
                && !$user->hasRole('admin')
            ) {
                return [
                    'status' => ['nullable', 'string', Rule::in(TaskStatus::values())],
                ];
            }
        }

        return [
            'title' => ['sometimes', 'required', 'string', 'max:255'],
            'description' => ['nullable', 'string', 'max:10000'],
            'assigned_to' => ['nullable', 'string'],
            'status' => ['nullable', 'string', Rule::in(TaskStatus::values())],
            'priority' => ['nullable', 'string', Rule::in(TaskPriority::values())],
            'access' => ['nullable', 'string', Rule::in(TaskAccess::values())],
            'due_at' => ['nullable', 'date'],
        ];
    }

    protected function prepareForValidation()
    {
        if ($this->has('due_at') && $this->input('due_at') === '') {
            $this->merge(['due_at' => null]);
        }
    }

    public function withValidator($validator)
    {
        $user = $this->user();
        $taskId = $this->route('id');

        // Admin/staff không được giao task cho owner
        if (!$user->hasRole('owner') && $this->filled('assigned_to')) {
            $bin = IdFormatter::hexToBinary($this->input('assigned_to'));
            if ($bin) {
                $target = \App\Models\User::find($bin);
                if ($target && $target->hasRole('owner')) {
                    $validator->errors()->add('assigned_to', 'Không thể giao việc cho chủ sở hữu.');
                    return;
                }
            }
        }

        if (!$taskId) return;

        $binId = IdFormatter::hexToBinary($taskId);
        $task = $binId ? Task::find($binId) : null;
        if (!$task
            || $user->id !== $task->assigned_to
            || $user->id === $task->created_by
            || $user->hasRole('owner')
            || $user->hasRole('admin')
        ) return;

        $allowed = ['status', '_token'];
        $extra = array_diff(array_keys($this->all()), $allowed);
        if (!empty($extra)) {
            $validator->errors()->add('_general', 'Bạn chỉ được phép cập nhật trạng thái của công việc này.');
        }
    }

    public function attributes(): array
    {
        $user = $this->user();
        $taskId = $this->route('id');

        if ($taskId) {
            $binId = IdFormatter::hexToBinary($taskId);
            $task = $binId ? Task::find($binId) : null;
            if ($task
                && $user->id === $task->assigned_to
                && $user->id !== $task->created_by
                && !$user->hasRole('owner')
                && !$user->hasRole('admin')
            ) {
                return [
                    'status' => 'Trạng thái',
                ];
            }
        }

        return [
            'title' => 'Tiêu đề',
            'description' => 'Mô tả',
            'assigned_to' => 'Người được giao',
            'status' => 'Trạng thái',
            'priority' => 'Mức ưu tiên',
            'access' => 'Đối tượng xem',
            'due_at' => 'Hạn hoàn thành',
        ];
    }
}
