<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use Carbon\Carbon;
use App\Models\ChatRoom;
use App\Models\Chat;
use App\Models\UserUsage;
use DB;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Http;
use MongoDB\Driver\Session;

class ChatController extends Controller
{
    public function createRoom(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'chat_id'   => 'required||max:36|unique:chat_rooms,chat_id',
            'name'      => 'nullable|string|max:400',
            'subject_id'=> 'required',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation errors',
                'errors' => $validator->errors()
            ], 200);
        }

        $room = ChatRoom::create([
            'user_id'   => $request->user()->id,
            'chat_id'   => $request->chat_id,
            'name'      => $request->name ?? '',
            'subject_id'=> $request->subject_id,
        ]);

        $room_data = array('id'=>$room->id,'name'=>"$room->name",'user_id'=>$room->user_id,'chat_id'=>"$room->chat_id",'subject_id'=>"$room->subject_id");

        return response()->json([
            'success'   => true,
            'message'   => 'Room created successfully.',
            'room'      => $room_data
        ], 200);
    }

    public function renameChatRoom(Request $request)
    {
        $request->validate([
            'id'    => 'required|exists:chat_rooms,id',
            'name'  => 'required|string|max:400',
        ]);

        $user_id    = $request->user()->id;
        $chatRoom   = ChatRoom::find($request->id);
        
        if ($chatRoom->user_id !== $user_id) {
            return response()->json(['success' => false, 'message' => 'Unauthorized.'], 200);
        }

        $chatRoom->update(['name' => $request->name]);

        $room_data = array('id'=>$chatRoom->id,'name'=>"$chatRoom->name",'user_id'=>$chatRoom->user_id,'chat_id'=>"$chatRoom->chat_id",'subject_id'=>"$chatRoom->subject_id");

        return response()->json([
            'success'   => true,
            'message'   => 'Chat room renamed successfully.',
            'room'      => $room_data
        ], 200);
    }

    // public function createChatOld(Request $request)
    // {
    //     $validator = Validator::make($request->all(), [
    //         // 'user_id'       =>'required|exists:users,id',
    //         'user_id' => [
    //                         'required',
    //                         function ($attribute, $value, $fail) {
    //                             if ($value !== 'AI' && !\DB::table('users')->where('id', $value)->exists()) {
    //                                 $fail('The selected user_id is invalid.');
    //                             }
    //                         },
    //                     ],
    //         'c_id'          =>'required|exists:chat_rooms,id',
    //         'ai_personality'=>'nullable',
    //         'audio_format'  =>'nullable',
    //         'tts'           =>'nullable',
    //         'text'          =>'nullable',
    //         'audio_base64'  =>'nullable',
    //         'images_base64' =>'nullable|array',
    //         'images_base64.*' => 'string',
    //     ]);

    //     if ($validator->fails()) {
    //         return response()->json([
    //             'success'   => false,
    //             'message'   => 'Validation errors',
    //             'errors'    => $validator->errors()
    //         ], 200);
    //     }

    //     $images_base64 = null;
    //     if($request->images_base64!=null && count($request->images_base64)>0){
    //         $images_base64 = json_encode($request->images_base64);
    //     }

    //     $insert = Chat::create([
    //         'user_id'       =>$request->user_id,
    //         'c_id'          =>$request->c_id,
    //         'ai_personality'=>$request->ai_personality,
    //         'audio_format'  =>$request->audio_format,
    //         'tts'           =>$request->tts,
    //         'text'          =>$request->text,
    //         'audio_base64'  =>$request->audio_base64,
    //         'images_base64' =>$images_base64,
    //         'created_at'    =>Carbon::now()
    //     ]);

    //     if($insert)
    //     {
    //         $insert->images_base64 = $insert->images_base64 != null ? json_decode($insert->images_base64) : null;
    //         return response()->json([
    //             'success'   => true,
    //             'message'   => 'Chat room renamed successfully.',
    //             'chat'      => $insert
    //         ], 200);
    //     }
    //     else{
    //         return response()->json([
    //             'success'   => false,
    //             'message'   => 'Oops something went wrong',
    //             'chat'      => new \stdClass(),
    //         ], 200);
    //     }
    // }

    public function createChat(Request $request)
    {
        ini_set('max_execution_time', '0');
        
        $validator = Validator::make($request->all(), [
            'subject_id'    =>  'nullable',
            'chat_id'       =>  'required',
            'ai_personality'=>  'nullable',
            'audio_format'  =>  'nullable',
            'tts'           =>  'nullable',
            'text'          =>  'nullable',
            'audio_base64'  =>  'nullable',
            'images_base64' =>  'nullable|array',
            // 'images_base64.*' => 'string',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success'   => false,
                'message'   => 'Validation errors',
                'errors'    => $validator->errors()
            ], 200);
        }
        
        
        $session = DB::getMongoClient()->startSession();
        $session->startTransaction();

        $user_id        = $request->user()->id;
        $user_name      = $request->user()->name;
        $images_base64  = [];

        if($request->images_base64!=null && count($request->images_base64)>0){
            $images_base64 = $request->images_base64;
        }
        
        $cr_name        = $request->text != null
                                ? Str::limit($request->text, 36, '...')
                                : ($request->images_base64 != null
                                    ? 'Image File'
                                    : ($request->audio_base64 != null
                                        ? 'Audio File'
                                        : null));

        try 
        {    
            $this->findUsages($request);
            $checkRoom  = ChatRoom::firstOrCreate(['chat_id'=>$request->chat_id],['user_id'=>$user_id,'name'=>$cr_name,'subject_id'=>$request->subject_id]);
            $chat_id    = $checkRoom->id;
            $insert     = Chat::create([
                            'user_id'       =>$user_id,
                            'c_id'          =>$chat_id,
                            'ai_personality'=>$request->ai_personality,
                            'audio_format'  =>$request->audio_format,
                            'tts'           =>true,
                            'text'          =>$request->text,
                            'audio_base64'  =>$request->audio_base64,
                            'images_base64' =>json_encode($images_base64),
                        ]);

            if($insert)
            {
                //MATH API
                $payload    = [
                    'user_id'   => $user_id,
                    'userName'  => $user_name,
                    'chat_id'   => $request->chat_id,
                    'text'      => "$request->text",
                    'ai_personality'=>$request->ai_personality,
                    'tts'       =>  true,
                ];

                if($request->images_base64!=null && count($request->images_base64)>0){
                    $payload['images_base64'] = $request->images_base64;
                }

                if($request->audio_base64!=null){
                    $payload['audio_base64'] = "$request->audio_base64";
                    $payload['audio_format'] = 'webm';
                }

                $res    = Http::withOptions([
                            'timeout' => 0,
                            'connect_timeout' => 0,
                        ])->withHeaders([
                            'X-API-Key'     => 'dGVjaHNhZ2FtYXRoc2Fp',
                            'Content-Type'  => 'application/json',
                        ])->withBody(
                            json_encode($payload)
                        )->post('https://maithsai.cdnmv.com/api/chat');
                
                $response = $res->body();
                $response = json_decode($response);

                if($res->successful())
                {
                    //AI RESPONSE ENTRY
                    $insert2    = Chat::create([
                        'user_id'       =>'AI',
                        'c_id'          =>$chat_id,
                        'ai_personality'=>$request->ai_personality,
                        'audio_format'  =>'webm',
                        'tts'           =>1,
                        'text'          =>$response->aiagent ?? null,
                        'audio_base64'  =>$response->audio ?? null,
                        'images_base64' =>null,
                        'graph_base64'  =>$response->graph_base64 ?? null,
                    ]);
                    
                    $response->audio_base64 = $response->audio ?? null;
                    $response->id           = $insert2->id;
                    $response->feedback     = false;

                    $session->commitTransaction();
                    return response()->json([
                        'success'   => true,
                        'message'   => 'Chat successfully.',
                        'chat'      => $response
                    ], 200);
                }
                else{
                    $session->abortTransaction();
                    return response()->json([
                        'success'   => false,
                        'message'   => $res,
                        'chat'      => new \stdClass(),
                    ], 200);
                }

                // $url = 'https://maithsai.cdnmv.com/api/chat'; 
                
                // $headers = [
                //     'X-API-Key: dGVjaHNhZ2FtYXRoc2Fp',
                //     'Content-Type: application/json',
                // ];

                // $ch = curl_init($url);

                // curl_setopt_array($ch, [
                //     CURLOPT_RETURNTRANSFER => true,
                //     CURLOPT_POST => true,
                //     CURLOPT_POSTFIELDS => json_encode($payload),
                //     CURLOPT_HTTPHEADER => $headers,
                //     CURLOPT_CONNECTTIMEOUT => 0, // 0 means no timeout
                //     CURLOPT_TIMEOUT => 0,        // 0 means no timeout
                // ]);

                // $response = curl_exec($ch);

                // // Check for cURL error
                // if (curl_errno($ch)) {
                //     $error = curl_error($ch);
                //     curl_close($ch);
                //     return response()->json([
                //         'success' => false,
                //         'error' => $error,
                //     ]);
                // }

                // $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                // curl_close($ch);

                // // Decode response
                // $decoded = json_decode($response, true);
                // dd($decoded);

                // // Optional: check if decoding failed
                // if (json_last_error() !== JSON_ERROR_NONE) {
                //     return response()->json([
                //         'success' => false,
                //         'error' => 'Invalid JSON response',
                //         'raw_response' => $response,
                //     ]);
                // }

                // // Check HTTP status code
                // if ($httpCode >= 200 && $httpCode < 300) {

                //     $insert2    = Chat::create([
                //                     'user_id'       =>'AI',
                //                     'c_id'          =>$chat_id,
                //                     'ai_personality'=>$request->ai_personality,
                //                     'audio_format'  =>'webm',
                //                     'tts'           =>1,
                //                     'text'          =>$decoded->aiagent ?? null,
                //                     'audio_base64'  =>$decoded->audio ?? null,
                //                     'images_base64' =>null,
                //                     'graph_base64'  =>$decoded->graph_base64 ?? null,
                //                 ]);
                            
                //     $decoded->audio_base64 = $decoded->audio ?? null;
                //     return response()->json([
                //         'success' => true,
                //         'chat' => $decoded,
                //     ]);
                // } else {
                //     return response()->json([
                //         'success' => false,
                //         'http_status' => $httpCode,
                //         'chat' => $decoded,
                //     ]);
                // }
            }
            else{
                $session->abortTransaction();
                return response()->json([
                    'success'   => false,
                    'message'   => 'Oops something went wrong',
                    'chat'      => new \stdClass(),
                ], 200);
            }
        } catch (\Exception $e) {
            $session->abortTransaction();
            return response()->json([
                'success'   => false,
                'message' => $e->getMessage()
            ], 200);
        }           

    }

    public function historyChatRoom(Request $request)
    {
        // $request->validate([
        //     'user_id'   => 'required|exists:users,id',
        // ]);

        
        $user_id    = $request->user()->id;

        $pinned     = ChatRoom::select('id','user_id','chat_id','name','subject_id')->where(['user_id'=>$user_id,'pin'=>1])->orderBy('created_at','DESC');
        $except     = $pinned->pluck('id')->toArray();
        $pinned     = $pinned->get();

        $chatRoom   = ChatRoom::select('id','user_id','chat_id','name','subject_id')->where('user_id',$user_id)->whereNotIn('id',$except)->orderBy('created_at','DESC')->get();

        $chatRoomToday = ChatRoom::select('id','user_id','chat_id','name','subject_id')
                    ->where('user_id', $user_id)
                    ->whereNotIn('id', $except)
                    ->whereDate('created_at', Carbon::today())
                    ->orderBy('created_at', 'DESC')
                    ->get();

        $chatRoomYesterday = ChatRoom::select('id','user_id','chat_id','name','subject_id')
                    ->where('user_id', $user_id)
                    ->whereNotIn('id', $except)
                    ->whereDate('created_at', Carbon::yesterday())
                    ->orderBy('created_at', 'DESC')
                    ->get();

        $chatRoomLast7Days = ChatRoom::select('id','user_id','chat_id','name','subject_id')
                    ->where('user_id', $user_id)
                    ->whereNotIn('id', $except)
                    ->whereBetween('created_at', [
                        Carbon::yesterday()->subDays(5)->startOfDay(),
                        Carbon::yesterday()->startOfDay()
                    ])
                    ->orderBy('created_at', 'DESC')
                    ->get();

        $chatRoomPrevious = ChatRoom::select('id','user_id','chat_id','name','subject_id')
                    ->where('user_id', $user_id)
                    ->whereNotIn('id', $except)
                    // ->where('created_at', '<', Carbon::now()->startOfWeek())
                    ->where('created_at', '<', Carbon::yesterday()->subDays(5)->startOfDay())
                    ->orderBy('created_at', 'DESC')
                    ->get();

        return response()->json([
            'success'   => true,
            'message'   => 'Chat room History.',
            'pinned'    => $pinned,
            'today'     => $chatRoomToday,
            'yesterday' => $chatRoomYesterday,
            'week'      => $chatRoomLast7Days,
            'previous'  => $chatRoomPrevious,
            'list'      => $chatRoom
        ], 200);
    }

    public function historyChat(Request $request)
    {
        $request->validate([
            'chat_id'      =>'required|exists:chat_rooms,chat_id',
        ]);

        $user_id    = $request->user()->id;
        $c_room     = ChatRoom::where('chat_id',$request->chat_id)->first();
        $c_id       = $c_room->id;
        // $chat       = Chat::select('chats.id','chats.feedback','chats.user_id','chats.c_id','chats.ai_personality','chats.audio_format','chats.tts','chats.text','chats.audio_base64','chats.graph_base64','chats.images_base64','cr.chat_id','cr.subject_id','sm.name','cr.subject_id')
        //                     ->leftjoin('chat_rooms as cr','cr.id','=','chats.c_id')
        //                     ->leftjoin('subject_masters as sm','sm.id','=','cr.subject_id')
        //                     // ->where(['chats.c_id'=>$c_id])
        //                     ->orderBy('chats.created_at','ASC')
        //                     ->get()
        //                     ->map(function ($item) {
        //                         // Decode specific JSON columns
        //                         $item->images_base64 = ($item->images_base64 != null) ? json_decode($item->images_base64, true) : null;
        //                         return $item;
        //                     });
        
        $chat       = Chat::raw(function ($collection) use ($c_id) {
                            return $collection->aggregate([
                                ['$match' => ['c_id' => $c_id]],
                                [
                                    '$lookup' => [
                                        'from' => 'tb',
                                        'localField' => 'c_id',
                                        'foreignField' => 'id',
                                        'as' => 'cr'
                                    ]
                                ],
                                ['$unwind' => ['path' => '$cr', 'preserveNullAndEmptyArrays' => true]],
                                [
                                    '$lookup' => [
                                        'from' => 'tc',
                                        'localField' => 'cr.subject_id',
                                        'foreignField' => 'id',
                                        'as' => 'sm'
                                    ]
                                ],
                                ['$unwind' => ['path' => '$sm', 'preserveNullAndEmptyArrays' => true]],
                                [
                                    '$project' => [
                                        'id' => 1,
                                        'feedback' => 1,
                                        'user_id' => 1,
                                        'c_id' => 1,
                                        'ai_personality' => 1,
                                        'audio_format' => 1,
                                        'tts' => 1,
                                        'text' => 1,
                                        'audio_base64' => 1,
                                        'graph_base64' => 1,
                                        'images_base64' => 1,
                                        'chat_id' => '$cr.chat_id',
                                        'subject_id' => '$cr.subject_id',
                                        'subject_name' => '$sm.name',
                                        'created_at' => 1,
                                    ]
                                ],
                                ['$sort' => ['created_at' => 1]],
                            ]);
                        });

        $chat = collect($chat)->map(function ($item) {
            $item['images_base64'] = isset($item['images_base64']) ? json_decode($item['images_base64'], true) : null;
            return $item;
        });
                        
        return response()->json([
            'success'   => true,
            'message'   => 'Chat History.',
            'list'      => $chat
        ], 200);
    }

    public function findUsages($request)
    {
        $user_id = $request->user()->id;
        if(isset($request->text) && $request->text!=null)
        {
            $wordCount      = str_word_count($request->text);
            $record         = UserUsage::where('type', 'word')
                                ->whereDate('record_date', now())
                                ->where('user_id',$user_id)
                                ->latest('record_date')
                                ->first();

            if ($record) {
                $record->usage += $wordCount;
                $record->save();
            } else {
                UserUsage::create([
                    'user_id' => $user_id,
                    'type' => 'word',
                    'usage' => $wordCount,
                    'record_date' => now(),
                ]);
            }
        }

        if(isset($request->audio_length) && $request->audio_length!=null)
        {
            $audioLength    = $request->audio_length;
            $record         = UserUsage::where('type', 'audio')
                                ->whereDate('record_date', now())
                                ->where('user_id',$user_id)
                                ->latest('record_date')
                                ->first();

            if ($record) {
                $record->usage += $audioLength;
                $record->save();
            } else {
                UserUsage::create([
                    'user_id' => $user_id,
                    'type' => 'audio',
                    'usage' => $audioLength,
                    'record_date' => now(),
                ]);
            }
        }

        if(isset($request->images_base64) && count($request->images_base64)>0)
        {
            $imageCount     = count($request->images_base64);
            $record         = UserUsage::where('type', 'image')
                                ->whereYear('record_date', now()->year)
                                ->whereMonth('record_date', now()->month)
                                ->where('user_id',$user_id)
                                ->latest('record_date')
                                ->first();

            if ($record) {
                $record->usage += $imageCount;
                $record->save();
            } else {
                UserUsage::create([
                    'user_id' => $user_id,
                    'type' => 'image',
                    'usage' => $imageCount,
                    'record_date' => now(),
                ]);
            }
        }
    }

    public function feedbackChat(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'id'        =>  'required|integer',
            'feedback'  =>  'required|integer|in:0,1',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'success'   => false,
                'message'   => 'Validation errors',
                'errors'    => $validator->errors()
            ], 200);
        }

        $chat = Chat::find($request->id);
        if($chat!=null)
        {
            $chat->feedback = $request->feedback;
            $chat->save();

            return response()->json([
                'success'   => true,
                'message'   => 'Thank you for feedback.'
            ], 200);
        }
        return response()->json([
            'success'   => false,
            'message'   => 'Something went wrong. Try again later.'
        ], 200);
    }

}
