<?php

namespace Wave\Http\Controllers\User;

use App\Events\ChatEvent;
use App\Http\Controllers\Controller;
use App\Models\SiteSetting;
use App\Models\Role;
use App\Models\User;
use App\Models\Permission;
use App\Models\PermissionGroup;
use App\Models\PermissionRole;
use App\Models\UserAccessLog;
use App\Models\ServiceChat;
use App\Models\ServiceChatMessage;
use App\Models\CompanySubscription;
use App\Models\Company;
use App\Models\CompanyMember;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Notification;
use Wave\Notifications\VerifyEmail;

class DashboardController extends Controller
{
    public function index()
    {
        $current_user = \Auth::user();
        return view('theme::user.dashboard');
    }

    public function generalInformation()
    {
        $current_user = \Auth::user();
        $company = Company::where('id', $current_user->company_id)->first();
        $company_members = CompanyMember::where('company_id', $current_user->company_id)->get();

        return view('theme::user.general-information',[
            'company' => $company,
            'company_members' => $company_members,
        ]);
    }

    public function userManagement()
    {
        $roles_id = [Role::OWNER_ROLE, Role::ADMINISTRATOR_ROLE, Role::BOOKKEEPER_ROLE, Role::COMPANY_SECRETARY_ROLE];
        $current_user = \Auth::user();

        $roles = Role::whereIn('id', $roles_id)->get();
        $company_users = User::with('userRole')->where('company_id', $current_user->company_id)->get();
        $user_ids = User::where('company_id', $current_user->company_id)->pluck('id');
        $user_logs = UserAccessLog::whereIn('user_id', $user_ids)->orderBy('created_at', 'desc')->get();
        $permission_group = PermissionGroup::with('permissions')->where('platform', 'client')->get();

        return view('theme::user.user-management', [
            'roles' => $roles,
            'company_users' => $company_users,
            'user_logs' => $user_logs,
            'permission_group' => $permission_group,
        ]);
    }

    public function userTermsAndCondition()
    {
        $siteSetting = SiteSetting::latest()->first();
        return view('theme::user.terms-and-condition', [
            'siteSetting' => $siteSetting,
        ]);
    }

    public function userPrivacyPolicy()
    {
        $siteSetting = SiteSetting::latest()->first();
        return view('theme::user.privacy-policy', [
            'siteSetting' => $siteSetting,
        ]);
    }

    public function createUser(Request $request)
    {
        $request->validate([
            'email' => 'required|unique:users,email',
            'first_name' => 'required',
            'last_name' => 'required',
            'password' => 'required',
            'phone' => 'required',
            'role_id' => 'required',
            'status' => 'required',
        ]);

        $verification_code = \Str::random(30);
        $verified = false;

        $current_user = $request->user();
        $user_data = $request->all();
        $user_data['password'] = \Hash::make($request->get('password'));
        $user_data['name'] = $request->get('first_name') . ' ' . $request->get('last_name');
        $user_data['username'] = $request->get('first_name') . \Str::random(5);
        $user_data['company_id'] = $current_user->company_id;

        $new_user = User::create($user_data);

        $new_user->verification_code = $verification_code;
        $new_user->save();

        Notification::route('mail', $request->get('email'))->notify(new VerifyEmail($new_user));

        return response()->json([
            'success' => true,
            'message' => 'user successfully created',
        ]);

    }

    public function updateUser(Request $request)
    {
        $request->validate([
            'user_id' => 'required',
            'email' => 'required',
            'first_name' => 'required',
            'last_name' => 'required',
            'phone' => 'required',
            'role_id' => 'required',
            'status' => 'required',
        ]);

        $email_exist = User::where('email', $request->get('email'))->where('id', '<>', $request->get('user_id'))->first();
        if ($email_exist) {
            return response()->json([
                'success' => false,
                'message' => 'Email already exist!',
            ]);
        }

        User::where('id', $request->get('user_id'))->update([
            'email' => $request->get('email'),
            'first_name' => $request->get('first_name'),
            'last_name' => $request->get('last_name'),
            'phone' => $request->get('phone'),
            'role_id' => $request->get('role_id'),
            'status' => $request->get('status'),
        ]);

        if ($request->get('password') === $request->get('confirm_password')) {
            User::where('id', $request->get('user_id'))->update([
                'password' => \Hash::make($request->get('password')),
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'user successfully updated',
        ]);
    }

    public function deleteUser(Request $request)
    {
        $request->validate([
            'user_id' => 'required',
        ]);

        User::where('id', $request->get('user_id'))->delete();

        return response()->json([
            'success' => true,
            'message' => 'user successfully deleted',
        ]);
    }

    public function getChatMessages($serviceType)
    {
        $newCollection = collect();
        $chat = ServiceChat::where('company_id', request()->user()->company_id)
            ->where('user_id', request()->user()->id)
            ->where('service_type', $serviceType)
            ->first();
        if (! $chat) {
            $chat = new ServiceChat();
            $chat->company_id = request()->user()->company_id;
            $chat->user_id = request()->user()->id;
            $chat->service_type = $serviceType;
            $chat->save();
        }
        $messages = $chat ? $chat->messages : null;
        if ($messages) {
            $newCollection = $messages->map(function ($message) {
                $message->date = $message->created_at->format('Y-m-d');
                $message->is_own_message = request()->user()->id == $message->from_user_id ? true : false;
                $message->elapsed_time = $message->elapsed_time;
                $message->message = $message->is_file ? '<a href="' . $message->file_url . '" target="_blank">' . $message->file_name . '</a>' : $message->message;

                return $message;
            })
            ->groupBy('date')
            ->map(function ($message) {
                return $message->flatmap(function ($item) use ($message) {
                    return [
                        'date' => $item->created_at->format('d F, Y'),
                        'messages' => $message,
                    ];
                });
            })
            ->values()
            ->all();
        }

        return response()->json([
            'success' => true,
            'data' => $newCollection,
            'chat_id' => $chat->id,
        ]);
    }

    public function sendChat(Request $request)
    {
        $chat = ServiceChat::where('company_id', $request->user()->company_id)
            ->where('user_id', $request->user()->id)
            ->where('service_type', $request->chat_service_type)
            ->first();
        if (! $chat) {
            $chat = new ServiceChat();
            $chat->company_id = $request->user()->company_id;
            $chat->user_id = $request->user()->id;
            $chat->service_type = $request->chat_service_type;
            $chat->save();
        }

        $messageFileName = '';
        if ($request->hasFile('chat_message_file')) {
            $file = $request->file('chat_message_file');
            $messageFileName = $request->file('chat_message_file')->getClientOriginalName();
            $file->storePubliclyAs($chat->folder_path, $messageFileName);
        }

        ServiceChatMessage::create([
            'service_chat_id' => $chat->id,
            'message' => $request->chat_message,
            'from_user_id' => $request->user()->id,
            'to_admin' => true,
            'is_file' => $messageFileName ? true : false,
            'file_name' => $messageFileName,
        ]);
        
        ChatEvent::dispatch($chat->id, true);

        storeUserNotification(null, 'Service Chat', $request->chat_message, 'Service Chat', true, $chat->id, 'service_chat');

        return response()->json([
            'success' => true,
        ]);
    }

    public function getUserList(Request $request)
    {
        $current_user = $request->user();
        $company_users = User::with('userRole')->where('company_id', $current_user->company_id)->where('id', '<>', $current_user->id)->get();

        return response()->json([
            'status' => true,
            'company_users' => $company_users,
        ]);
    }

    public function getUserData(Request $request, $user_id)
    {
        $current_user = $request->user();
        $user = User::with('userRole')->where('company_id', $current_user->company_id)->where('id', $user_id)->first();

        if ($user) {
            return response()->json([
                'status' => true,
                'user' => $user,
            ]);
        }

        return response()->json([
            'status' => false,
            'message' => 'User doest not exist on this company',
        ]);
    }

    public function getCompanyUserRoles(Request $request)
    {
        $roles_id = [Role::OWNER_ROLE, Role::ADMINISTRATOR_ROLE, Role::BOOKKEEPER_ROLE, Role::COMPANY_SECRETARY_ROLE];

        $roles = Role::whereIn('id', $roles_id)->get();
        return response()->json([
            'status' => false,
            'roles' => $roles,
        ]);

    }

    public function getCompanyUsersAccessLogs(Request $request)
    {
        $current_user = $request->user();
        $user_ids = User::where('company_id', $current_user->company_id)->pluck('id');
        $logs = UserAccessLog::whereIn('user_id', $user_ids)->get();

        return response()->json([
            'status' => false,
            'logs' => $logs,
        ]);
    }

    public function getPermissionGroup(Request $request)
    {
        $group = PermissionGroup::with('permissions')->where('platform', 'client')->get();
        return response()->json([
            'status' => false,
            'group' => $group,
        ]);
    }

    public function getPermissionOfRole(Request $request, $role_id)
    {
        $current_user = $request->user();

        $permission = PermissionRole::with('permission')->where('company_id', $current_user->company_id)->where('role_id', $role_id)->get();

        return response()->json([
            'status' => false,
            'permission' => $permission,
        ]);
    }

    public function addPermissionToRole(Request $request)
    {
        $request->validate([
            'role_id' => 'required',
            'permission_id' => 'required',
        ]);

        $current_user = $request->user();

        $permission = PermissionRole::where('role_id', $request->role_id)
        ->where('permission_id', $request->permission_id)
        ->where('company_id', $current_user->company_id)->first();

        if (! $permission) {
            PermissionRole::create([
                'role_id' => $request->role_id,
                'permission_id' => $request->permission_id,
                'company_id' => $current_user->company_id,
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'permission successfully added',
        ]);
    }

    public function removePermissionToRole(Request $request)
    {
        $request->validate([
            'role_id' => 'required',
            'permission_id' => 'required',
        ]);

        $current_user = $request->user();

        $permission = PermissionRole::where('role_id', $request->role_id)
        ->where('permission_id', $request->permission_id)
        ->where('company_id', $current_user->company_id)->delete();

        return response()->json([
            'success' => true,
            'message' => 'permission successfully remove',
        ]);
    }

    public function roleHasPermission(Request $request)
    {
        $request->validate([
            'role_id' => 'required',
            'permission_id' => 'required',
        ]);

        $current_user = $request->user();

        $permission = PermissionRole::where('role_id', $request->role_id)
        ->where('permission_id', $request->permission_id)
        ->where('company_id', $current_user->company_id)->first();

        if($permission) {
            return response()->json([
                'success' => true,
                'message' => 'role has this permission',
            ]);
        }

        return response()->json([
            'success' => false,
            'message' => 'role dont have this permission',
        ]);
    }
}
