<?php

namespace App\Http\Controllers;

use App\Domain\Messenger\Models\ChatRoom;
use App\Domain\Messenger\Models\Message;
use App\Models\User;
use Inertia\Inertia;
use Illuminate\Support\Facades\Request;
use Illuminate\Http\Request as HttpRequest;
use Illuminate\Database\Eloquent\Builder;


class MessengerController extends Controller
{

    protected function getSearchByMessage($currentUser, $search)
    {
        return $currentUser
        ->chat_rooms()
        ->orderBy('updated_at', 'desc')
        ->with(['messsages' => function ($query) use($search) {
            $query->where('message', 'ilike', "{$search}%");
        }, 'users:id,first_name,last_name,username,photo_path,banner_path,color,user_char'])
        ->whereHas('messsages', function (Builder $query) use($search) {
            $query->where('message', 'ilike', "{$search}%");
        })
        ->get();
    }

    protected function getSearchByUser($currentUser, $search)
    {
        return $currentUser
        ->chat_rooms()
        ->orderBy('updated_at', 'desc')
        ->with(['users:id,first_name,last_name,username,photo_path,banner_path,color,user_char', 'messsages'])
        ->whereHas('users', function (Builder $query) use($search) {
            $query->where('first_name', 'ilike', '%'.$search.'%')
                    ->orWhere('last_name', 'ilike', '%'.$search.'%');
        })
        ->get();
    }

    public function index()
    {
        // Если пользователь выбирается по гет параметру
        $chatSelectUser = null;
        $chatSelectUserID = 0;
        if($getUsername = request()->get('user')){
            $chatSelectUser = User::where('username', $getUsername)->firstOrFail();
            $chatSelectUser->name = $chatSelectUser->name;
            $chatSelectUserID = $chatSelectUser->id;
        }

        $search = request()->get('search');
        $type = request()->get('type');
        $currentUser = auth()->user();

        if($search){
            if($type == 1){
                $chat_rooms = $this->getSearchByMessage($currentUser, $search);
            }else{
                $chat_rooms = $this->getSearchByUser($currentUser, $search);
            }

            $chat_rooms->transform(function ($room) {
                $message = $room->messsages->first();
                $room->latestMessage = $message;
                return $room;
            });
        }else{
            $chat_rooms = $currentUser
            ->chat_rooms()
            ->orderBy('updated_at', 'desc')
            ->with('latestMessage', 'users:id,first_name,last_name,username,photo_path,banner_path,color,user_char')
            ->get();
        }

        $rooms = $chat_rooms->map(function ($room) use ($currentUser, $chatSelectUserID) {
            $is_my_message = false;
            $classActive = false;
            if($room->latestMessage->user_id === $currentUser->id){
                $is_my_message = true;
            }
            $message = $room->latestMessage->message;
            $updated_at_human = $room->latestMessage->created_at->diffForHumans();
            $updated_at = $room->latestMessage->created_at->format('U');

            $correspond = $room->users->where('id', '<>', $currentUser->id)->first();
            unset($correspond->pivot);
            $correspond->name = $correspond->name;
            if($chatSelectUserID === $correspond->id){ // делаем активным
                $classActive = true;
            }
            return [
                'id' => $room->id,
                'is_freeze' => $room->is_freeze,
                'classActive' => $classActive,
                'is_my_message' => $is_my_message,
                'message' => $message,
                'is_reading' => $room->latestMessage->is_reading,
                'updated_at' => $updated_at,
                'updated_at_human' => $updated_at_human,
                'correspond' => $correspond->toArray(),
            ];
        });

        if($chatSelectUserID){
            $checkActiveRoom = $rooms->contains(function ($item) {
                return $item['classActive'] === true;
            });
            if(!$checkActiveRoom){
                $globalRoomUser = $this->isRoomCreate($chatSelectUserID);
                if($globalRoomUser){
                    $globalRoomUser->load('latestMessage');
                    $is_my_message = false;
                    if($globalRoomUser->latestMessage->user_id === auth()->user()->id){
                        $is_my_message = true;
                    }
                    $new_room = [
                        'id' => $globalRoomUser->id,
                        'is_freeze' => $globalRoomUser->is_freeze,
                        'classActive' => true,
                        'is_my_message' => $is_my_message,
                        'message' => $globalRoomUser->latestMessage->message,
                        'is_reading' => $globalRoomUser->latestMessage->is_reading,
                        'updated_at' => $globalRoomUser->updated_at->format('U'),
                        'updated_at_human' => $globalRoomUser->updated_at->diffForHumans(),
                        'correspond' => $chatSelectUser->only(['id','name','first_name','last_name','photo_path','banner_path','color','user_char', 'username']),
                    ];
                    $rooms[] = $new_room;
                }
            }
            $rooms = $rooms->sortByDesc('classActive')->values();
        }

        return Inertia::render('Messenger/Index', [
            'rooms' => $rooms,
            'roomSearch' => $search,
        ]);
    }


    public function show($id)
    {
        $room = ChatRoom::findOrFail($id);
        $search = request()->get('search');

        $messages = $room->messsages()->with('user:id,first_name,photo_path,color,user_char')->orderBy('id');
        if($search){
            $messages = $messages->where('message', 'ilike', "{$search}%");
        }
        $messages = $messages->cursorPaginate(50);
        $nextCursor = get_cursor_hash($messages);



        $messages->each(function ($message) {
            if($message->is_reading === false && $message->user_id != auth()->user()->id){
                $message->is_reading = true;
                $message->save();
            }
            $message->group = $message->created_at->format('d.m.Y');
            $message->created = $message->created_at->format('H:i');
            return $message;
        });
        $messages = $messages->groupBy(function ($val) {
            return \Carbon\Carbon::parse($val->created_at)->format('d.m.Y');
        });

        return ['records' =>  $messages, 'cursor' => $nextCursor];


    }

    public function store(HttpRequest $request)
    {
        $message = $request->input('params.message');
        $chat_room_id = $request->input('params.room');
        $status = $this->createMessage($message, $chat_room_id);
        if($status === false){
            return null;
        }
        return $status;
    }

    public function storeFromProfile(HttpRequest $request)
    {
        $message = $request->input('message');
        $chat_room_id = $request->input('chat_room');

        $status = $this->createMessage($message, $chat_room_id);
        if($status === false){
            return redirect()->back()->with('error', 'Вы не можете отправить сообщение данному пользователю');
        }

        return redirect()->back()->with('success', 'Сообщение успешно отправлено!');
    }

    protected function createMessage($text, $chat_room_id)
    {
        $user = auth()->user();
        $chatRoom = ChatRoom::find($chat_room_id);
        if($chatRoom->is_freeze){
            return false;
        }
        $message = new Message;
        $message->message = $text;
        $message->user_id = $user->id;
        $message->chat_room_id = $chat_room_id;
        $message->save();

        $chatRoom->touch();

        $message->created = $message->created_at->format('H:i');
        $message->updated_at_room_human = $message->created_at->diffForHumans();
        $message->updated_at_room = $message->created_at->format('U');
        $message->group = $message->created_at->format('d.m.Y');
        $message->keyGroupDate = $message->created_at->format('d.m.Y');
        $message->user = $user->only(['id','first_name','photo_path','color','user_char']);

        return $message;
    }

    public function checkRoom(HttpRequest $request)
    {
        $userId = $request->input('params.user');
        $room = $this->isRoomCreate($userId);
        return $room ? $room->id : 0;
    }

    protected function isRoomCreate($userId)
    {
        return auth()->user()->chat_rooms()->whereHas('users', function (Builder $query) use($userId) {
            $query->where('id', $userId);
        })->first();
    }

    public function createRoom(HttpRequest $request)
    {
        $message = $request->input('message');
        $user_id = $request->input('user_id');

        $existBannedUsers = $this->getBannedUser($user_id);
        if($existBannedUsers){
            return redirect()->back()->with('error', 'Вы не можете отправить сообщение данному пользователю');
        }

        $room = new ChatRoom;
        $room->save();
        $room->users()->attach([$user_id, auth()->user()->id]);

        $this->createMessage($message, $room->id);

        return redirect()->back()->with('success', 'Сообщение успешно отправлено!');
    }

    public function freezeRoom(HttpRequest $request)
    {
        $room_id = $request->input('room');
        $room = ChatRoom::find($room_id);
        $roomUsers = $room->users;
        $isAuthUserExist = $roomUsers->contains(fn($user) => $user->id === auth()->user()->id);
        $correspond = $roomUsers->where('id', '<>', auth()->user()->id)->first();
        if(!$isAuthUserExist){
            return redirect()->back()->with('error', 'Доступ запрещен');
        }

        // добавляем пользователя
        $status = auth()->user()->bannedUsers()->toggle([$correspond->id]);

        // проверяем есть ли пользователя из чата в черном списке, если есть замораживаем чат
        $existBannedUsers = $this->getBannedUser($correspond->id);

        if($existBannedUsers){ //disable touch update_at column
            \DB::table('chat_rooms')->where('id', $room->id)->update(['is_freeze' => true]);
        }else{
            \DB::table('chat_rooms')->where('id', $room->id)->update(['is_freeze' => false]);
        }

        $msg = 'Пользователь успешно удален из чернго списка';
        if(count($status['attached'])){
            $msg = 'Пользователь успешно добавлен в черный список';
        }

        return redirect()->back()->with('success', $msg);
    }

    public function checkBannedUser(HttpRequest $request)
    {
        $correspond_id = $request->input('params.user');
        $partnerIsBanned = \DB::table('user_banned')
        ->where('user_id', auth()->user()->id)
        ->where('banned_user_id', $correspond_id)->count();
        if($partnerIsBanned){
            return ['banned' => true];
        }

        return ['banned' => false];
    }

    public function leaveRoom(HttpRequest $request)
    {
        $room_id = $request->input('room');

        $room = ChatRoom::find($room_id);
        $room->users()->detach(auth()->user()->id);

        return redirect()->back()->with('success', 'Успешно покинули беседу');
    }


    public function removeMessage($id)
    {
        $message = Message::findOrFail($id);
        $message->delete();

        return ['success' => true];
    }

    protected function getBannedUser($correspondId)
    {
        return \DB::table('user_banned')
        ->where('user_id', auth()->user()->id)
        ->where('banned_user_id', $correspondId)
        ->orWhere(function($query) use($correspondId) {
            $query->where('user_id', $correspondId)
                  ->where('banned_user_id', auth()->user()->id);
        })->count();
    }
}
