<?php

namespace App\Http\Controllers;

use App\Models\Gift;
use App\Models\User;
use App\Models\Space;
use App\Models\Category;
use App\Models\BlockUser;
use App\Models\Followers;
use App\Models\ReportSpace;
use App\Models\SpaceMember;
use App\Models\SubCategory;
use App\Models\Transaction;
use App\Models\Notification;
use App\Models\SpaceCheckIn;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Resources\UserShortResource;
use Illuminate\Support\Facades\Validator;
use App\Classes\AgoraDynamicKey\RtcTokenBuilder;

// include ("./../app/Classes/AgoraDynamicKey/RtcTokenBuilder.php");
class SpaceController extends Controller
{
    public function createSpace(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required',
            'description' => 'required',
            'is_paid' => 'required',
            'amount' => 'required_if:is_paid,1',
            'privacy' => 'required',
            'topic' => 'required',
            'status' => 'required',

        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $loggedInUser = $request->user();
        $status = $request->status;
        if ($status == 'active') {
            Space::where(['user_id' => $loggedInUser->id, 'status' => 'active'])->update(['status' => 'completed']);
        }
        $space = new Space;
        $space->user_id = $loggedInUser->id;
        $space->title = $request->title;
        $space->description = $request->description;
        $space->status = $request->status;
        $space->topic = $request->topic;
        if (!empty($request->is_paid)) {
            $space->is_paid = 1;
            $space->amount = $request->amount;
        } else {
            $space->is_paid = 0;
            $space->amount = 0;
        }
        $space->privacy = $request->privacy ?? 1;
        $appID = setting('agora_app_id');
        $appCertificate = setting('agora_app_id');
        $channelName = $request->title . rand(1, 100);
        $role = RtcTokenBuilder::RolePublisher;
        $expireTimeInSeconds = 7200;
        $currentTimestamp = now()->getTimestamp();
        $privilegeExpiredTs = $currentTimestamp + $expireTimeInSeconds;
        $token = RtcTokenBuilder::buildTokenWithUid($appID, $appCertificate, $channelName, 0, $role, $privilegeExpiredTs);
        $space->agora_token_id = $token;
        $space->start_time = $request->start_time;
        $space->save();
        $space_id = $space->id;
        SpaceMember::create(['user_id' => $loggedInUser->id, 'space_id' => $space_id, 'is_host' => 1]);
        $spaceModel = new Space;
        $spacedata = Space::find($space->id);
        $spacedetails = $spaceModel->getsingleSpace($spacedata, $loggedInUser->id);
        return response()->json(['status' => 200, 'message' => 'Space is created', 'data' => $spacedetails], 200);
    }


    public function getSpaces(Request $request)
    {
        $limit = $request->limit ?? 10;
        $offset = $request->offset ?? 0;
        $user_id  = $request->user()->id;
        $spaces = Space::where('user_id', '!=', $user_id)->where('status', 'active')->limit($limit)->offset($offset)->get();
        if (!empty($spaces)) {
            foreach ($spaces as $space) {
                $space['host'] = new UserShortResource($space->userdata) ?? null;
                $space->makeHidden('userdata');
            }
        }
        return response()->json(['status' => 200, 'message' => 'Spaces found successfully', 'data' => $spaces], 200);
    }
    public function joinSpace(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',


        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json(['status' => 400, 'message' => 'Space not found'], 200);
        }
        $user = $request->user();
        if ($space->user_id == $user->id) {
            return response()->json(['status' => 400, 'message' => 'Can not join your own space'], 200);
        }
        $checkOldUser = SpaceMember::where(['space_id' => $space_id, 'user_id' => $user->id])->first();
        if (!empty($checkOldUser)) {
            return response()->json(['status' => 400, 'message' => 'Already Joined'], 200);
        }
        if ($space->is_paid == 1) {
            $user_wallet = getUserWallet($user->id);
            if ($user_wallet < $space->amount) {
                return response()->json(['status' => 400, 'message' => 'Insufficent balance '], 200);
            }
            $transaction = new Transaction();
            $transaction->user_id = $space->user_id;
            $transaction->type = 'credit';
            $transaction->amount = $space->amount;
            $transaction->wallet_id = walletId();
            $transaction->description = 'join space for (ID:' . $space_id . ')';
            $transaction->refrence_type = 'join_space';
            $transaction->refrence_id = $space_id;
            $transaction->metadata = "{action:join_space}";
            $transaction->save();
            $transaction = new Transaction();
            $transaction->user_id = $space->user_id;
            $transaction->type = 'debit';
            $transaction->amount = $space->amount;
            $transaction->wallet_id = walletId();
            $transaction->description = 'join space for (ID:' . $space_id . ')';
            $transaction->refrence_type = 'join_space';
            $transaction->refrence_id = $space_id;
            $transaction->metadata = "{action:join_space}";
            $transaction->save();
        }
        SpaceMember::create(['user_id' => $user->id, 'space_id' => $space_id]);
        Notification::create([
            'from_user_id' => Auth::id(),
            'to_user_id' => $space->user_id,
            'type' => 'join_space',
            'text' => 'joined your space',
            'space_id' => $space->id,
        ]);
        return response()->json(['status' => 200, 'message' => 'Space Joined successfully'], 200);
    }


    public function sendNotification($from_user_id, $to_user_id, $text, $notification_type, $space_id = 0, $gift_id = 0)
    {
        $from_user = User::select(['username', 'profile_image'])->where('id', $from_user_id)->first();
        $to_user_id = User::select(['username', 'profile_image'])->where('id', $to_user_id)->first();
    }
    public function pendingJoinRequest(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $user  = $request->user();
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json([
                'status' => 400,
                'message' => 'space not found',
            ]);
        }
        if ($space->user_id != $user->id) {
            return response()->json([
                'status' => 400,
                'message' => 'Un Authenticated',
            ]);
        }
        $users = [];
        $spacemembers = SpaceMember::where(['space_id' => $space_id, 'join_status' => 2])->get();
        if (!empty($spacemembers)) {
            $userModel = new User;
            $user = [];
            foreach ($spacemembers as $member) {
                $user = $userModel->usershortInfo($member->user_id);
                $user['request_id'] = $member->id;
                $users[] = $user;
            }
            return response()->json([
                'status' => 200,
                'message' => 'Pending Request fetch  successfully',
                'data' => $users
            ]);
        }
    }
    public function approveSpaceJoinRequest(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'request_id' => 'required',
        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $user = $request->user();
        $request_id = $request->request_id;

        $joinRequest = SpaceMember::where(['id' => $request_id, 'join_status' => 2])->first();

        if (empty($joinRequest)) {
            return response()->json([
                'status' => 400,
                'message' => 'Join request not found',
            ]);
        }

        $space = Space::find($joinRequest->space_id);
        if (empty($space)) {
            return response()->json([
                'status' => 400,
                'message' => 'Space not found',
            ]);
        }
        if ($user->id != $space->user_id) {
            return response()->json([
                'status' => 400,
                'message' => 'Un Authenticated',
            ]);
        }
        $joinRequest->join_status = 1;
        $joinRequest->update();
        $space->increment('members');
        return response()->json([
            'status' => 200,
            'messsage' => 'Request approved successfully',
        ]);
    }
    public function removeMember(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
            'user_id' => 'required',

        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $user_id = $request->user_id;
        $space = Space::find($space_id);
        $loggedInUser = $request->user();

        if (empty($space)) {
            return response()->json([
                'status' => 400,
                'message' => 'Space not found',
            ]);
        }
        if ($loggedInUser->id != $space->user_id) {
            return response()->json([
                'status' => 400,
                'message' => 'Un Authenticated',
            ]);
        }
        $userrecord = SpaceMember::where(['user_id' => $user_id, 'space_id' => $space_id])->first();
        if (empty($userrecord)) {
            return response()->json([
                'status' => 400,
                'message' => 'User not found',
            ]);
        }
        $userrecord->delete();
        $space->decrement('members');
        return response()->json([
            'status' => 200,
            'message' => 'The user is removed successfully',
        ]);
    }
    public function addCoHost(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
            'user_ids' => 'required',

        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $userIdString = $request->user_ids;
        $userIdArray = explode(",", $userIdString);
        $loggedInUser = $request->user();
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json([
                'status' => 400,
                'message' => 'Space not found',
            ]);
        }
        if ($loggedInUser->id != $space->user_id) {
            return response()->json([
                'status' => 400,
                'message' => 'Un Authenticated',
            ]);
        }
        if (count($userIdArray) > 0) {
            foreach ($userIdArray as $user_id) {
                $user = User::find($user_id);
                $userrecord = SpaceMember::where(['user_id' => $user_id, 'space_id' => $space_id, 'is_cohost' => 0, 'join_status' => 1])->first();
                if (!empty($userrecord) && !empty($user)) {
                    $userrecord->is_cohost = 1;
                    $userrecord->update();
                }
            }
            return response()->json([
                'status' => 200,
                'message' => 'Cohost added successfully',
            ]);
        }
        return response()->json([
            'status' => 400,
            'message' => 'Please select listener to make the cohost',
        ]);
    }
    public function removeCoHost(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
            'user_ids' => 'required',

        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $userIdString = $request->user_ids;
        $space = Space::find($space_id);
        $userIdArray = explode(",", $userIdString);
        if (empty($space)) {
            return response()->json([
                'status' => 400,
                'message' => 'Space not found',
            ]);
        }
        if ((in_array($space->user_id, $userIdArray))) {
            return response()->json([
                'status' => 400,
                'message' => 'Un Authenticated',
            ]);
        }
        foreach ($userIdArray as $user_id) {
            $user =  User::find($user_id);
            $userrecord = SpaceMember::where(['user_id' => $user_id, 'space_id' => $space_id, 'is_cohost' => 1])->first();
            if (!empty($user) && !empty($userrecord)) {
                $userrecord->is_cohost = 0;
                $userrecord->update();
            }
            return response()->json([
                'status' => 200,
                'message' => 'Cohost removed successfully',
            ]);
        }
        return response()->json([
            'status' => 200,
            'message' => 'Please select speaker to remove ',
        ]);
    }

    public function sendGift(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'user_id' => 'required',
            'gift_id' => 'required',
        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $gift_id = $request->input('gift_id');
        $user_id = $request->input('user_id');
        $loggedInUser = $request->user()->id;

        // Check if the user is trying to send a gift to themselves
        if ($user_id == $loggedInUser) {
            return response()->json([
                'status' => 400,
                'message' => 'You cannot send the gift to yourself',
            ], 200);
        }
        $gift = Gift::find($gift_id);
        $user = User::find($user_id);

        // Check if the gift exists
        if (!$gift) {
            return response()->json([
                'status' => 400,
                'message' => 'Gift not found',
            ], 200);
        }
        $user_balance = getUserWallet($loggedInUser);

        if ($gift->price > $user_balance) {
            return response()->json([
                'status' => 400,
                'message' => 'Insufficient balance',
            ], 200);
        }
        Transaction::create([
            'user_id' => $user_id,
            'flag' => 'C',
            'description' => 4,
            'gift_id' => $gift_id,
            'amount' => $gift->price,
        ]);

        Transaction::create([
            'user_id' => $loggedInUser,
            'flag' => 'D',
            'description' => 4,
            'gift_id' => $gift_id,
            'amount' => $gift->price,
        ]);
        Notification::create([
            'from_user_id' => $loggedInUser,
            'to_user_id' => $user_id,
            'gift_id' => $gift_id,
            'notification_type' => 'deposit_amount',
            'text' => 'sent you a gift'
        ]);
        Notification::create([
            'from_user_id' => $user_id,
            'to_user_id' => $loggedInUser,
            'gift_id' => $gift_id,
            'notification_type' => 'deductt_amount',
            'text' => 'deduct amount due to sending gift'
        ]);
        return response()->json([
            'status' => 200,
            'message' => 'Gift successfully sent.',
        ], 200);
    }
    public function updateSpace(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json(['status' => 400, 'message' => 'Space not found'], 200);
        }
        $inputData = $request->all();
        $user = $request->user();
        $updateData = [];
        foreach ($inputData as $fieldName => $fieldValue) {
            if ($fieldName != 'space_id' && $fieldName != 'cohost_ids') {
                $updateData[$fieldName] = $fieldValue;
            }
            if ($fieldName == 'start_time') {
                $updateData[$fieldName] = convertTimeToUTC($fieldValue);
            }
        }
        Space::where('id', $space_id)->update($updateData);
        $cohosts = $request->cohost_ids;

        if (!empty($cohosts)) {
            $cohostArray = explode(',', $cohosts);

            SpaceCheckIn::where('space_id', $space_id)->whereNotIn('user_id', $cohostArray)->delete();
            foreach ($cohostArray as $CohostId) {
                SpaceCheckIn::updateOrCreate(
                    ['space_id' => $space_id, 'user_id' => $CohostId, 'is_cohost' => 1],
                );
            }
        }
        return response()->json([
            'status' => 200,
            'message' => 'Space is updated',
        ]);
    }
    public function getSpaceMembers(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $userModel = new User;
        $speakers = [];
        $linters = [];
        $limit = $request->limit ?? 10;
        $offset = $request->offset ?? 0;

        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json(['status' => 400, 'message' => 'space not found '], 200);
        }
        if ($space->status == 'upcoming') {
            return response()->json(['status' => 400, 'message' => 'space is not active'], 200);
        }
        $speakers  = SpaceMember::where('space_id', $space_id)
            ->where(function ($query) {
                $query->where('is_host', 1)
                    ->orWhere('is_cohost', 1);
            })
            ->limit($limit)
            ->offset($offset)
            ->get();
        if (!empty($speakers) && count($speakers) > 0) {
            foreach ($speakers as $speaker) {
                $userdata = $userModel->usershortInfo($speaker->user_id);
                $userdata['is_host'] = $speaker->is_host;
                $userdata['is_cohost'] = $speaker->is_cohost;
                $allMembers['speakers'][] = $userdata;
            }
        }

        $allMembers['listeners'] = [];
        $listners  = SpaceMember::where(['space_id' => $space_id, 'is_host' => 0, 'is_cohost' => 0])->limit($limit)->offset($offset)->get();
        $allMembers['total_members_count'] =  count($listners) + count($speakers);
        if (!empty($listners)) {
            foreach ($listners as $listner) {
                $userdata = $userModel->usershortInfo($listner->user_id);
                $userdata['is_host'] = 0;
                $userdata['is_cohost'] = 0;
                $allMembers['listeners'][] = $userdata;
            }
        }



        return response()->json([
            'status' => 200,
            'message' => 'Space members fetch successfully',
            'data' => $allMembers,
        ]);
    }

    public function leaveSpace(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
        ]);
        if ($validator->fails()) {
            $first_error = $validator->errors()->first();
            return response()->json(['status' => 400, 'message' => $first_error], 200);
        }
        $space_id = $request->space_id;
        $loggedInUserId = $request->user()->id;
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json([
                'status' => 400,
                'message' => 'Space not found',
            ]);
        }
        if ($space->status != 'active') {
            return response()->json([
                'status' => 400,
                'message' => 'Space is not live',
            ]);
        }
        if ($space->user_id == $loggedInUserId) {
            $space->status = 'completed';
            $space->update();
            $user  = User::find($space->user_id);
            if ($user->status == 2) {
                $user->tokens()->delete();
            }
            return response()->json([
                'status' => 200,
                'message' => 'Space left successfully',
            ]);
        }
        $spaceMember = SpaceMember::where(['space_id' => $space_id, 'user_id' => $loggedInUserId])->first();
        if (empty($spaceMember)) {
            return response()->json([
                'status' => 400,
                'message' => 'User is not in this space',
            ]);
        }
        $spaceMember->delete();
        $space->decrement('members');
        return response()->json([
            'status' => 200,
            'message' => 'Space left successfully',
        ]);
    }





    public function reportSpace(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
            'reason' => 'required',
        ]);
        if ($validator->fails()) {
            return response()->json(['status' => 400, 'message' => $validator->errors()->first()], 200);
        }
        $space_id = $request->space_id;
        $loggedInUser = $request->user();
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json(['status' => 400, 'message' => 'space not found'], 200);
        }
        if ($space->user_id == $loggedInUser->id) {
            return response()->json(['status' => 400, 'message' => "Can't report your own space"], 200);
        }
        if ($space->status != 'active') {
            return response()->json(['status' => 400, 'message' => "You can  report only live space"], 200);
        }
        $checkexistreport = ReportSpace::where(['user_id' => $loggedInUser->id, 'space_id' => $space_id])->first();
        if (!empty($checkexistreport)) {
            return response()->json(['status' => 400, 'message' => "You already reported this space"], 200);
        }
        ReportSpace::create(['user_id' => $loggedInUser->id, 'space_id' => $space_id, 'reason' => $request->reason]);
        return response()->json(['status' => 200, 'message' => "space reported successfully"], 200);
    }

    public function spaceDetails(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
        ]);
        if ($validator->fails()) {
            return response()->json(['status' => 400, 'message' => $validator->errors()->first()], 200);
        }
        $space_id = $request->space_id;
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json(['status' => 400, 'message' => 'space not found'], 200);
        }


        $spaceModel = new Space;

        $spaceDetail = $spaceModel->getsingleSpace($space, Auth::id());
        return response()->json(['status' => 200, 'message' => 'space details fetch successfully', 'data' => $spaceDetail], 200);
    }
    public function deleteSpace(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'space_id' => 'required',
        ]);
        if ($validator->fails()) {
            return response()->json(['status' => 400, 'message' => $validator->errors()->first()], 200);
        }
        $space_id = $request->space_id;
        $space = Space::find($space_id);
        if (empty($space)) {
            return response()->json(['status' => 400, 'message' => 'space not found'], 200);
        }
        if ($space->status != 'upcoming') {
            return response()->json(['status' => 400, 'message' => 'Can Delete Only Upcoming space '], 200);
        }
        if ($space->is_paid == 1) {
            $space_users = SpaceCheckIn::where(['space_id' => $space->id, 'payment_status' => 1, 'is_cohost' => 0])->pluck('user_id')->toArray();
            foreach ($space_users as $joiner) {
                $transactionModel = new Transaction();
                $transactionModel->reverseTransaction($space, $joiner);
            }
        }
        SpaceCheckIn::where(['space_id' => $space->id])->delete();
        Space::where('id', $space_id)->delete();
        return response()->json(['status' => 200, 'message' => 'Space deleted successfully'], 200);
    }
}
