<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\ApiToken;
use App\Models\Subscription as SubscriptionTBL;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Mail\SendOTPMail;
use Carbon\Carbon;
use App\Models\Trial;
use Illuminate\Support\Facades\Mail;
use DB;
use Http;
use Storage;


class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name'      => 'required',
            'email'     => [
                'required',
                'email',
                Rule::unique('users')->where(function ($query) {
                    return $query->where('is_email_verified', true);
                }),
            ],
            'dob'       => 'nullable|date|date_format:Y-m-d|before:today',
            'password'  => 'required|min:6',
        ]);
    
        if ($validator->fails()) {
            return response()->json([
                'success' => false,
                'message' => 'Validation errors',
                'errors' => $validator->errors()
            ], 200);
        }

        // Generate OTP
        $otp = rand(100000, 999999);
        // $otp = 999999;
        $otpExpiry = Carbon::now()->addMinutes(10); // OTP valid for 10 minutes

        
        $user = User::updateOrCreate(
            [   
                'email' => $request->email
            ],
            [
                'name'      => $request->name,
                'password'  => Hash::make($request->password),
                'dob'       => $request->dob,
                'otp'       => $otp,
                'otp_expires_at'    => $otpExpiry,
                'status'    =>  "1",
                'is_email_verified' => "0",
            ]
        );

        $token = '';

        try {
            Mail::to($user->email)->send(new SendOTPMail($user));
        } catch (\Exception $e) {
            \Log::error('Mail sending failed: ' . $e->getMessage());
        }
        // Mail::to($user->email)->send(new SendOTPMail($user));

        return response()->json([
            'success' => true,
            'message' => 'User registered successfully',
            'data' => [
                'user_id'  => $user->id,
                'token' => $token
            ]
        ], 200);
    }

    //  Login API
    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required|min:6',
        ], [
            'email.required' => 'The email field is required.',
            'email.email' => 'Please enter a valid email address.',
            'password.required' => 'The password field is required.',
            'password.min' => 'Password must be at least 6 characters long.',
        ]);
        
        // If validation fails, return JSON response
        if ($validator->fails()) {
            return response()->json([
                'success'    => false,
                'message'   => 'Validation failed',
                'errors'    => $validator->errors()
            ], 200);
        }
        
        $user = User::select('id','name','email','password','is_email_verified','status','dob','avatar','parent_email')
                        ->where('email', $request->email)
                        ->first();
        
        if ($user == null || !Hash::check($request->password, $user->password) || $user->is_email_verified=='0') {
            return response()->json([
                'success'    => false,
                'message'   => 'Invalid email or password.'
            ], 200);
        }
        
        if($user!=null && $user->status=='0')
        {
            return response()->json([
                'success'    => false,
                'message'   => 'Your account is inactive. Please contact to support',
            ], 200);
        }

        // $token = $user->createToken('authToken')->plainTextToken;
        $token = bin2hex(random_bytes(40)); // 80 chars
        $hashedToken = hash('sha256', $token);
        ApiToken::create([
            'user_id' => $user->id,
            'token' => $hashedToken,
            'abilities' => ['*'],
            'created_at' => now(),
        ]);

        $user->avatar = ($user->avatar!=null)?asset('storage').'/'.$user->avatar : '';
        return response()->json([
            'success'    => true,
            'message'   => 'Login successful',
            'data'      => [
                'user'  => $user,
                'token' => $token
            ]
        ], 200);
    }

    public function verifyOtp(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'user_id'   => 'required|exists:users,id',
            'otp'       => 'required|numeric',
        ]);

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

        $user = User::find($request->user_id);

        // Check if OTP is valid
        if ($user->otp != $request->otp) {
            return response()->json(['success' => false, 'message' => 'Invalid OTP'], 200);
        }

        // Check if OTP is expired
        if (Carbon::now()->gt($user->otp_expires_at)) {
            return response()->json(['success' => false, 'message' => 'OTP expired'], 200);
        }

        // OTP is valid, clear OTP fields
        $user->otp = null;
        $user->otp_expires_at = null;
        $user->is_email_verified = '1';
        $user->email_verified_at = Carbon::now();
        $user->save();


        $trial = Trial::first();
        if($trial!=null && $trial->is_active==1 && $trial->trial_days>0 )
        {
            $startDate = now()->toDateString();
            $endDate = now()->addDays($trial->trial_days)->toDateString();
            DB::table('subscriptions')->insert([
                                        'user_id'   => $request->user_id,
                                        'stripe_subscription_id'=> 'Free Trial',
                                        'plan_id'   => '683012620ff455d317b8e6b4',
                                        'status'    => 'active',
                                        'payment_status'=> 1,
                                        'amount'    => '0',
                                        'start_at'  => $startDate,
                                        'end_at'    => $endDate,
                                        'is_trial'  => 1,
                                        'created_at'=> Carbon::now()
                                    ]);
        }

        // Generate auth token
        // $token  = $user->createToken('authToken')->plainTextToken;
        $token = bin2hex(random_bytes(40)); // 80 chars
        $hashedToken = hash('sha256', $token);
        ApiToken::create([
            'user_id' => $user->id,
            'token' => $hashedToken,
            'abilities' => ['*'],
            'created_at' => now(),
        ]);
        
        $avatar = ($user->avatar!=null)?asset('storage').'/'.$user->avatar : '';
        $data   = array('id'=>$user->id,'name'=>$user->name,'email'=>$user->email,'status'=>$user->status,'dob'=>$user->dob,'avatar'=>"$avatar",'parent_email'=>$user->parent_email);
        return response()->json([
            'success'   => true,
            'message'   => 'OTP verified successfully. You are logged in.',
            'data'      => [
                'user'  => $data,
                'token' => $token
            ]
        ], 200);
    }

    //  Profile API (Requires Authentication)
    public function profile(Request $request)
    {
        $user   = $request->user();
        return response()->json(['user'=>$request->user()]);
        $avatar = ($user->avatar!=null)?asset('storage').'/'.$user->avatar : '';
        $data   = array('id'=>$user->id,'name'=>$user->name,'email'=>$user->email,'status'=>$user->status,'dob'=>$user->dob,'avatar'=>"$avatar",'parent_email'=>"$user->parent_email");
        return response()->json([
            'success'   => true,
            'message'   => 'Profile Detail',
            'data'      => [
                'user'  => $data
            ]
        ], 200);
    }

    public function profileUpdate(Request $request)
    {
        $user   = $request->user();

        // $validator = Validator::make($request->all(), [
        //     'name'  => 'required|string|max:255',
        //     // 'email' => 'required|email|unique:users,email,' . $user->id,
        //     'dob'   => 'required|date|date_format:Y-m-d|before:today',
        //     'avatar'=> 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048', // 2MB max
        //     'parent_email' => 'required|email',
        // ]);

        $validator = Validator::make($request->all(), [
            'step'  => ['required', Rule::in([1, 2])], // Step must be 1 or 2
            'name'  => 'required_if:step,1|string|max:255',
            'dob'   => 'nullable|date|date_format:Y-m-d|before:today',
            'avatar'=> 'nullable|image|max:2048', // 2MB max image

            'parentName'    => 'required_if:step,2|string|max:255',
            'parentEmail'   => 'required_if:step,2|email',
            'frequency'     => 'required_if:step,2|string',
        ],[
            // Custom Messages
            'step.required' => 'The step field is required.',
            'step.in' => 'The step must be either 1 or 2.',
        
            'name.required_if' => 'The name field is required.',
            'name.string' => 'The name must be a valid string.',
            'name.max' => 'The name must not exceed 255 characters.',
        
            'dob.date' => 'The date of birth must be a valid date.',
            'dob.date_format' => 'The date of birth must be in Y-m-d format (e.g., 2000-05-15).',
            'dob.before' => 'The date of birth must be before today.',
        
            'avatar.image' => 'The avatar must be an image file.',
            'avatar.max' => 'The avatar must not be larger than 2MB.',
        
            'parentName.required_if' => 'The parent name is required.',
            'parentName.string' => 'The parent name must be a valid string.',
            'parentName.max' => 'The parent name must not exceed 255 characters.',
        
            'parentEmail.required_if' => 'The parent email is required.',
            'parentEmail.email' => 'The parent email must be a valid email address.',
        
            'frequency.required_if' => 'The frequency field is required.',
            'frequency.string' => 'The frequency must be a valid string.',
        ]);

        // If validation fails, return JSON response
        if ($validator->fails()) {
            return response()->json([
                'success'    => false,
                'message'   => 'Validation failed',
                'errors'    => $validator->errors()
            ], 200);
        }
    
        // Handle avatar upload (if provided)
        if ($request->hasFile('avatar')) {
            // $avatarPath = $request->file('avatar')->store('/', 'public/avatars');
            $file       = $request->file('avatar');
            $fileName   = $file->hashName();
            $file->storeAs('avatars', $fileName, 'public');
            $user->avatar = $fileName;
            // $user->avatar = $avatarPath;
        }
    
        // Update user details
        if($request->step == 1)
        {
            $user->update([
                'name'  => $request->name,
                'dob'   => $request->dob,
            ]);
        }
        else{
            $user->update([
                'parent_email'  => $request->parentEmail,
                'parent_name'   => $request->parentName,
                'frequency'     => $request->frequency,
            ]);
        }
        // $user->update([
        //     'name' => $request->name,
        //     'dob' => $request->dob,
        //     'parent_email' => $request->parent_email,
        // ]);
        $avatar = ($user->avatar!=null)?asset('storage/avatars').'/'.$user->avatar : '';
        $data   = array('id'=>$user->id,'name'=>$user->name,'email'=>$user->email,'status'=>$user->status,'dob'=>$user->dob,'avatar'=>"$avatar",'parent_email'=>"$user->parent_email",'parent_name'=>$user->parent_name,'frequency'=>$user->frequency);

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

    //  Logout API
    public function logout(Request $request)
    {
        $user = $request->user();

        if (!$user) {
            return response()->json([
                'success'   => false,
                'message'   => 'Unauthorized',
            ], 200);
        }

        $header = $request->header('Authorization');

        if (! $header || ! str_starts_with($header, 'Bearer ')) {
            return response()->json(['message' => 'Unauthorized'], 401);
        }

        $plainToken = substr($header, 7);
        $hashedToken = hash('sha256', $plainToken);

        $tokenRecord = ApiToken::where('token', $hashedToken)->delete();

        // $user->tokens()->delete();

        return response()->json([
            'success' => true,
            'message' => 'Logged out successfully',
        ], 200);
    }

    public function sendEmail()
    {
        Mail::raw('This is a test email from Laravel 12.', function ($message) {
            $message->to('saurabhrawat0007000@gmail.com')
                    ->subject('Test Email')
                    ->from(env('MAIL_FROM_ADDRESS'), env('MAIL_FROM_NAME'));
        });
    
        return "Email sent successfully!";
    }
    
    public function changePassword(Request $request)
    {
        $request->validate([
            'current_password' => 'required',
            'new_password' => 'required|min:6|confirmed',
        ]);

        $user = $request->user();

        if (!Hash::check($request->current_password, $user->password)) {
            return response()->json([
                'success'   => false,
                'message'   => 'Current password is incorrect',
            ], 200);
        }

        $user->update(['password' => Hash::make($request->new_password)]);

        return response()->json([
            'success' => true,
            'message' => 'Password changed successfully',
        ], 200);
    }

    public function deleteAccount(Request $request)
    {
        $user = $request->user();

        if (!$user) {
            return response()->json([
                'success'   => false,
                'message'   => 'Unauthorized',
            ], 200);
        }

        $user->tokens()->delete(); // Revoke all API tokens (Sanctum)
        $user->delete(); // Delete the user account

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


    public function socialLogin(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'social_id'   => 'required|string',
            'social_type' => 'required|string', // like "google" or "facebook"
            'name'        => 'required|string',
            'email'       => 'required|email',
            'dob'         => 'nullable|date|date_format:Y-m-d|before:today',
        ]);

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

        

        $user = User::where('email',$request->email)
                        ->where(function ($query) use ($request) {
                            $query->where('email',$request->email)
                            ->where('social_type','!=', $request->social_type)
                            ->orWhere(function ($query2) use ($request) {
                                $query2->where('email',$request->email)
                                ->whereNull('social_type');
                            });
                        })
                        ->orWhere(function ($query) use ($request) {
                            $query->where('email',$request->email)
                            ->where('social_id','!=', $request->social_id)
                            ->orWhere(function ($query2) use ($request) {
                                $query2->where('email',$request->email)
                                ->whereNull('social_id');
                            });
                        })
                        ->orWhere(function ($query) use ($request) {
                            $query->where('email',$request->email)
                            ->whereNull('social_type')
                            ->whereNull('social_id');
                        })
                        ->first();

        if ($user!=null) {
            return response()->json([
                'success' => false,
                'errors' => ['email' => ['Email Already Exist']]
            ]);
        }

        $userAvatar = null;
        if ($request->has('avatar') && $request->avatar!='') {
            // $avatarPath = $request->file('avatar')->store('/', 'public/avatars');
            $url       = $request->avatar;
            $response   = Http::get($url);
            $filename   = basename($url);
            Storage::disk('public')->put('avatars/' . $filename, $response->body());
            // $file->storeAs('avatars', $fileName, 'public');
            $userAvatar = $filename;
            // $user->avatar = $avatarPath;
        }

        $user = User::updateOrCreate(
            [   
                'social_id'     => $request->social_id,
                'social_type'   => $request->social_type
            ],
            [
                'name'          => $request->name,
                'password'      => 'N/A',
                'email'         => $request->email,
                'dob'           => $request->dob,
                'is_email_verified' => '1',
                'avatar'        => $userAvatar,
                'status'        => '1'
            ]
        );
        
        if ($user->wasRecentlyCreated) {

            $trial = Trial::first();
            if($trial!=null && $trial->is_active==1 && $trial->trial_days>0 )
            {
                $startDate  = now()->toDateString();
                $endDate    = now()->addDays($trial->trial_days)->toDateString();
                $tp_id      = env('DEFAULT_TP_ID');
                SubscriptionTBL::insert([
                                            'user_id'   => $user->id,
                                            'stripe_subscription_id'=> 'Free Trial',
                                            'plan_id'   => $tp_id,
                                            'status'    => 'active',
                                            'payment_status'=> 1,
                                            'amount'    => '0',
                                            'start_at'  => $startDate,
                                            'end_at'    => $endDate,
                                            'is_trial'  => 1,
                                            'created_at'=> Carbon::now()
                                        ]);
            }
        }

        $user  = User::select('id','name','email','status','dob','avatar','parent_email','password')->find($user->id);
        
        $user->avatar = ($user->avatar!=null)?asset('storage/avatars').'/'.$user->avatar : '';
        // $token = $user->createToken('authToken')->plainTextToken;

        $token = bin2hex(random_bytes(40)); // 80 chars
        $hashedToken = hash('sha256', $token);
        ApiToken::create([
            'user_id' => $user->id,
            'token' => $hashedToken,
            'abilities' => ['*'],
            'created_at' => now(),
        ]);
        
        return response()->json([
            'success' => true,
            'message' => 'Login successful',
            'data'    =>['user'  => $user,'token' => $token]
        ]);
    }

    public function resendOtp(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'user_id' => 'required|exists:users,id',
        ]);

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

        $user = User::where('id', $request->user_id)->first();

        $otp = rand(100000, 999999);
        // $otp = 999999;
        $otpExpiry = Carbon::now()->addMinutes(10); // OTP valid for 10 minutes

        
        $user = User::updateOrCreate(
            [   
                'email' => $user->email
            ],
            [
                'otp'       => $otp,
                'otp_expires_at'    => $otpExpiry,
            ]
        );

        $token = ''; //$user->createToken('authToken')->plainTextToken;

        Mail::to($user->email)->send(new SendOTPMail($user));

        return response()->json([
            'success' => true,
            'message' => 'OTP Resend Successfully',
            'data' => [
                'user_id'  => $user->id,
                'token' => $token
            ]
        ], 200);

    }
}
