<?php

namespace App\Http\Controllers\Api\Mobile;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Package;
use App\Models\Subscription;
use App\Models\User;
use App\Repositories\Interfaces\Auth\SocialAuthRepositoryInterface;
use App\Traits\ImageTrait;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use App\Traits\Mobile\ApiResponseTrait;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules\Password;
use App\Traits\EmailHandlerTrait;
use Laravel\Socialite\Facades\Socialite;

class AuthController extends Controller
{
    use ApiResponseTrait, EmailHandlerTrait, ImageTrait;
    protected $socialAuthRepo;

    public function __construct(SocialAuthRepositoryInterface $socialAuthRepo)
    {
        $this->socialAuthRepo = $socialAuthRepo;
    }
    public function login(Request $request)
    {
        // Validate input
        $validator = Validator::make($request->all(), [
            'email' => 'required|email',
            'password' => 'required',
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }

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

        if (!$user || !Hash::check($request->password, $user->password)) {
            return $this->responseWithError(__('invalid_credentials_or_not_admin'), 401);
        }
        $token = $user->createToken('api_token')->plainTextToken;

        $data = [
            'token' => $token,
            'type' => 'Bearer',
            'user' => $user,
        ];

        return $this->responseWithSuccess($data, __('login_successful'));
    }

    public function logout(Request $request)
    {
        $token = $request->user()->currentAccessToken();

        if ($token) {
            $token->delete();
            return response()->json(['message' => __('logged_out_successful')]);
        }

        return $this->responseWithError(__('no_token_found'), 400);
    }

    public function signup(Request $request)
    {
        // Validate input
        $validator = Validator::make($request->all(), [
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'required|email|unique:users,email',
            'password' => ['required', 'string', Password::defaults()],
            'confirm_password' => 'required|string|same:password',
            'user_type' => 'required|string',
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }

        $slug = 'flixoo-'.time();
        // 1. Create the Client first
        $client = new Client();
        $client->first_name = $request->first_name;
        $client->last_name = $request->last_name;
        $client->company_name = 'flixoo';
        $client->webhook_verify_token = Str::random(30);
        $client->api_key = Str::random(30);
        $client->slug = $slug;
        $client->save();

        // Create user
        $user = User::create([
            'username' => $request->username,
            'first_name' => $request->first_name,
            'last_name' => $request->last_name,
            'email' => $request->email,
            'status' => 1,
            'client_id' => $client->id,
            'user_type' => $request->user_type,
            'password' => Hash::make($request->password),
        ]);
        
        $user = User::where('email', $request->email)->first();
        $token = $user->createToken('api_token')->plainTextToken;
        $data = [
            'token' => $token,
            'type' => 'Bearer',
            'user' => $user,
        ];

        return $this->responseWithSuccess($data, __('sign_up_successful'));
    }

    public function socialLogin(Request $request)
    {
     
        Log::info('function hit');
        $validator = Validator::make($request->all(), [
              'access_token' => 'required|string',
              'provider' => 'required|in:google,facebook',
          ]);
        if ($validator->fails()) {
          return $this->responseWithValidation($validator->errors(), 422);
        }
      //  Log::info('request passed' . $request->all());

         try {
            $provider = $request->provider;

            // For Facebook, optionally specify email permission
            $driver = Socialite::driver($provider);
            Log::info('driver found');
            Log::info($request->access_token);

            if ($provider === 'facebook') {
                $driver->scopes(['email']);
            }

            $socialUser = $driver->userFromToken($request->access_token);
            Log::info('user found');

            $user = $this->socialAuthRepo->findOrCreateUserFromSocialite($socialUser);

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

            return $this->responseWithSuccess([
                'token' => $token,
                'user' => $user
            ], __('authenticated_successfully'));

         } catch (\Exception $e) {
             return $this->responseWithError([
                 'error' => __('authentication_failed'),
                 'message' => $e->getMessage()
             ], 500);
         }
    }

    
    public function get_user_details_by_id(Request $request)
    {
        $token = $request->user()->currentAccessToken();
        if ($token) {
            $user_details = User::where('id', $request->id)->first();
            $user_details->image = apiImageFromJson($user_details->image, 'original_image', 'users');
            $subscription = Subscription::where('client_id', $user_details->client?->id)->latest()->first();
            Log::info($subscription);
            if(isset($subscription->status) && $subscription->status == 1){
                $user_details->subscription_plan = Package::where('id', $user_details->subscription_id)->value('name') ?? null;
            } else{
                if($subscription){
                 $user_details->subscription_plan = 'Pending';
               }else{
               		$user_details->subscription_plan = 'Free';
               }
            }

            $data = [
                'user' => $user_details,
            ];
            return $this->responseWithSuccess($data, __('retrieve_data_successfully'));
        }
    }

    public function change_account_status(Request $request)
    {
        $token = $request->user()->currentAccessToken();
        if ($token) {
            // Validate input
            $validator = Validator::make($request->all(), [
                'id' => 'required|numeric',
                'value' => 'required|numeric',
            ]);
            if ($validator->fails()) {
                return $this->responseWithValidation($validator->errors(), 422);
            }
            $user = User::where('id', $request->id)->update(['status' => $request->value]);
            if ($user) {
                $data = [
                    'details' => '',
                ];
                return $this->responseWithSuccess($data, __('status_change_successfully'));
            }
        }
    }

    public function forgot_password(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string'
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }
        $otp = $this->sendOtpRequestToEmail($request->email);
        if ($otp) {
            $data = [
                'details' => $otp,
            ];
            return $this->responseWithSuccess($data, __('otp_send_successfully'));
        } else {
            return $this->responseWithError(__('fail_to_send_otp'), 400);
        }
    }
    public function phone_login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'phone' => 'required|string'
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }
        $user = $this->sendOtpRequestToPhone($request->phone);
        if ($user) {

            return $this->responseWithSuccess([$user->token], __('otp_send_successfully'));
        } else {
            return $this->responseWithError(__('fail_to_send_otp'), 400);
        }
    }

    public function otp_verify(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email_or_phone' => 'required|string',
            'otp' => 'required|numeric'
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }
        $data = $this->verifyOtp($request->email_or_phone, $request->otp);

        if (!empty($data['user'])) {
            $token = $data['user']->createToken('API Token')->plainTextToken;

            $response = [
                'user' => $data['user'],
                'token' => $token
            ];

            return $this->responseWithSuccess($response, $data['message']);
        } else {
            return $this->responseWithError($data['message'], 400);
        }
    }

    public function update_password(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|string',
            'password' => ['required', 'string', Password::defaults()],
            'confirm_password' => 'required|string|same:password'
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }
        $user = User::where('email', $request->email);
        if ($user->first()->token) {
            $user->update(['password' => Hash::make($request->password), 'token' => null]);
            return $this->responseWithSuccess(['details' => ''], __('password_updated_successfully'));
        }
        return $this->responseWithError(__('already_updated'), 400);
    }

    public function update_Profile(Request $request)
    {
        $user = auth()->user(); // or $request->user()

        $validator = Validator::make($request->all(), [
            'user_id' => 'required|numeric|exists:users,id',
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'phone' => 'nullable|string|max:50',
            'email' => 'required|string|email|max:255|unique:users,email,' . $request->input('user_id'),
            'gender' => 'nullable|numeric',
            'profile' => 'nullable|image|max:2048', // 'profile' must match the input name
        ]);

        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }
        DB::beginTransaction();
        try {
            $user = User::find($request['user_id']);
            
            // Handle image upload
            if ($request->hasFile('profile')) {
                $this->imageDelete($user['id'], 'user', 'image'); // delete old image
                $response = $this->saveImage($request->file('profile'), '_user_');
                $user->image = json_encode($response['images']);
            }
            
            // Update profile fields
            $user->first_name = $request['first_name'];
            $user->last_name = $request['last_name'];
            $user->phone = $request['phone'];
            $user->email = Str::lower((string) $request['email']);
            $user->gender = $request['gender'];
            $user->save();

            DB::commit();
            $user->image = apiImageFromJson($user->image, 'original_image', 'users');
            return $this->responseWithSuccess(['details' => $user], __('profile_updated_successfully'));
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->responseWithError(__('profile_update_failed') . $e->getMessage(), 500);
        }
    }


    public function change_password(Request $request)
    {
        $request->user()->currentAccessToken();

        $validator = Validator::make($request->all(), [
            'old_password' => 'required|string',
            'new_password' => ['required', 'string', Password::defaults()],
            'confirm_password' => 'required|string|same:new_password'
        ]);
        if ($validator->fails()) {
            return $this->responseWithValidation($validator->errors(), 422);
        }

        $user = $request->user();

        if (!Hash::check($request->old_password, $user->password)) {
            return $this->responseWithError(__('old_password_incorrect'), 400);
        }

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

        return $this->responseWithSuccess(['details' => ''], __('password_changed_successfully'));
    }

    public function delete_account($id)
    {
        $user = User::find($id);

        if (!$user) {
            return $this->responseWithError(__('user_not_found'), 404);
        }

        // Delete associated image
        $this->imageDelete($user->id, 'user', 'image');

        // Delete the user
        $user->delete();

        return $this->responseWithSuccess(['details' => ''], __('account_deleted_successfully'));
    }


}
