<?php

declare(strict_types=1);

namespace App\Policies;

use App\Http\Controllers\Concerns\AuthorizesProjectAccess;
use App\Models\Discussion;
use App\Models\DiscussionMessage;
use App\Models\Project;
use App\Models\User;

class DiscussionPolicy
{
    use AuthorizesProjectAccess;

    public function viewAny(User $user): bool
    {
        return true;
    }

    public function view(User $user, Discussion $discussion): bool
    {
        if ($user->hasRole('admin')) {
            return true;
        }

        if ($discussion->isParticipant($user)) {
            return true;
        }

        if ($discussion->project && $this->userCanAccessProject($user, $discussion->project)) {
            return true;
        }

        return $discussion->created_by === $user->id;
    }

    public function create(User $user, ?Project $project = null): bool
    {
        if ($user->hasRole('admin')) {
            return true;
        }

        if ($project === null) {
            return true;
        }

        return $this->userCanAccessProject($user, $project);
    }

    public function update(User $user, Discussion $discussion): bool
    {
        return $this->canManage($user, $discussion);
    }

    public function end(User $user, Discussion $discussion): bool
    {
        return $this->canManage($user, $discussion) && $discussion->isActive();
    }

    public function delete(User $user, Discussion $discussion): bool
    {
        return $this->canManage($user, $discussion) && $discussion->status !== Discussion::STATUS_DELETED;
    }

    public function postMessage(User $user, Discussion $discussion): bool
    {
        if (! $discussion->isActive()) {
            return false;
        }

        if ($user->hasRole('admin')) {
            return true;
        }

        if ($discussion->isBlocked($user)) {
            return false;
        }

        return $discussion->isParticipant($user) || $discussion->created_by === $user->id;
    }

    public function deleteMessage(User $user, Discussion $discussion, DiscussionMessage $message): bool
    {
        if ($message->discussion_id !== $discussion->id) {
            return false;
        }

        return $this->canManage($user, $discussion) || $message->user_id === $user->id;
    }

    public function block(User $user, Discussion $discussion): bool
    {
        return $this->canManage($user, $discussion);
    }

    private function canManage(User $user, Discussion $discussion): bool
    {
        if ($user->hasRole('admin') || $discussion->created_by === $user->id) {
            return true;
        }

        $project = $discussion->project()->with('producer')->first();

        return $project !== null && $this->userCanAccessProject($user, $project);
    }
}
