<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Admin;
use App\Models\Country;
use App\Models\Otp;
use App\Models\User;
use App\Traits\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use OpenApi\Attributes as OA;

class AuthController extends Controller
{
    use ApiResponse;



    #[OA\Post(
        path: '/api/signup',
        operationId: 'signup',
        summary: 'Register user',
        description: 'Creates a new user account and returns an access token.',
        tags: ['Auth'],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['full_name', 'phone', 'whatsapp_number', 'email', 'country_id', 'language_id'],
                properties: [
                    new OA\Property(property: 'full_name', type: 'string', example: 'John Doe'),
                    new OA\Property(property: 'phone', type: 'string', example: '9876543210'),
                    new OA\Property(property: 'whatsapp_number', type: 'string', example: '9876543210'),
                    new OA\Property(property: 'email', type: 'string', format: 'email', example: 'john@example.com'),
                    new OA\Property(property: 'country_id', type: 'integer', example: 1),
                    new OA\Property(property: 'language_id', type: 'integer', example: 1),
                    new OA\Property(property: 'referral_code', type: 'string', example: 'YAAME1234'),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 200,
                description: 'Signup successful',
                content: new OA\JsonContent(
                    properties: [
                        new OA\Property(property: 'success', type: 'integer', example: 1),
                        new OA\Property(property: 'message', type: 'string', example: 'Success'),
                        new OA\Property(
                            property: 'data',
                            properties: [
                                new OA\Property(property: 'token', type: 'string'),
                                new OA\Property(property: 'country', type: 'string', example: 'India'),
                                new OA\Property(property: 'language', type: 'string', example: 'English'),
                            ],
                            type: 'object'
                        ),
                    ]
                )
            ),
            new OA\Response(
                response: 422,
                description: 'Validation Error'
            )
        ]
    )]
    public function signup(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'full_name' => ['required', 'string', 'max:255'],
            'country_code' => ['required', 'string', 'max:10'],
            'phone' => ['required', 'string', 'max:255', 'unique:users'],
            'whatsapp_country_code' => ['nullable', 'string', 'max:10'],
            'whatsapp_number' => ['nullable', 'string', 'max:255', 'unique:users'],
            'email' => ['nullable', 'string', 'email', 'max:255', 'unique:users'],
            'country_id' => ['required', 'exists:countries,id'],
            'language_id' => ['required', 'string', 'max:255'],
            'referral_code' => ['nullable', 'string', 'max:255'],

        ]);


        if ($validator->fails()) {
            return $this->errorResponse($validator->errors()->first());
        }

         $check_referral=null;
         $referral_id=null;
         $referred_by_admin=null;

        if ($request->filled('referral_code')) {
            $check_referral = User::where('referral_code', $request->referral_code)->first();
            if (!$check_referral) {
                return $this->errorResponse('Invalid Referral Code');
            }
            $referral_id = $check_referral->id;

        }else{
            $referred_by_admin = Admin::where('role', 'super_admin')->first();
        }

        $currency = $request->country_id ? Country::find($request->country_id)->currency_code : 'USD';

        $user = new User();
        $user->full_name = $request->full_name;
        $user->country_code = $request->country_code;
        $user->phone = $request->phone;
        $user->whatsapp_country_code = $request->whatsapp_country_code;
        $user->whatsapp_number = $request->whatsapp_number;
        $user->email = $request->email;
        $user->country_id = $request->country_id;
        $user->language_id = $request->language_id;
        $user->referral_code = $this->generateReferralCode();
        $user->referred_by = $referral_id;
        $user->referred_by_admin_id = $referred_by_admin->id ?? null;
        $user->currency = $currency;
        $user->save();

        $token = $user->createToken('auth_token')->accessToken;

        return $this->successResponse('Success', [
            'token' => $token,
            'country' => $user->country->name,
            'language' => $user->language->name,
            'currency_code' => $user->country->currency_code
        ]);
    }

    private function generateReferralCode(): string
    {
        do {
            $referralCode = 'YAAME' . mt_rand(1000, 9999);
        } while (
            User::where('referral_code', $referralCode)->exists()
        );

        return $referralCode;
    }



    public function send_otp(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'phone' => ['required', 'string', 'max:255'],
            'country_code' => ['required', 'string', 'max:10'],
        ]);

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

        $otp = mt_rand(1000, 9999);

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


        if (!$user) {
            return $this->errorResponse('User not found');
        }

        Otp::create([
            'phone' => $request->phone,
            'country_code' => $request->country_code,
            'code' => $otp,
        ]);


        return $this->successResponse('OTP sent successfully', [
            'otp' => $otp
        ]);
    }

    public function verifyOtp(Request $request)
    {

        $validator = Validator::make($request->all(), [
            'country_code' => ['required', 'string', 'max:10'],
            'phone' => ['required', 'string', 'max:255'],
            'otp' => ['required', 'string', 'max:255'],
        ]);

        if ($validator->fails()) {
            return $this->errorResponse($validator->errors()->first());
        }

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

        if ($user) {
            $otp = Otp::where('phone', $request->phone)->where('country_code', $request->country_code)->first();

            if ($otp) {
                if ($otp->code == $request->otp) {
                   $token = $user->createToken('auth_token')->accessToken;

                    Otp::where('phone', $request->phone)->where('country_code', $request->country_code)->delete();



                    return $this->successResponse('OTP verified', [
                        'token' => $token,
                        'country' => $user->country->name,
                        'language' => $user->language->name,
                        'currency_code' => $user->country->currency_code
                    ]);
                } else {
                    return $this->errorResponse('Invalid OTP');
                }
            }
        }
    }

    public function user_status()
    {
        $user = Auth::user();
        return $this->successResponse('User status', [
            'user_id' => $user->id,
            'full_name' => $user->full_name,
            'email' => $user->email,
            'status' => $user->status
        ]);
    }







    #[OA\Post(
        path: '/api/auth/register',
        operationId: 'authRegister',
        summary: 'Register a new user',
        description: 'Creates a new user account and returns a Sanctum Bearer token.',
        tags: ['Auth'],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['name', 'email', 'phone', 'password', 'password_confirmation'],
                properties: [
                    new OA\Property(property: 'name',                  type: 'string',  example: 'Ronio Doe'),
                    new OA\Property(property: 'email',                 type: 'string',  format: 'email', example: 'ronio@example.com'),
                    new OA\Property(property: 'phone',                 type: 'string',  example: '+2348012345678'),
                    new OA\Property(property: 'password',              type: 'string',  format: 'password', minLength: 8, example: 'secret123'),
                    new OA\Property(property: 'password_confirmation', type: 'string',  format: 'password', example: 'secret123'),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 201,
                description: 'Registration successful',
                content: new OA\JsonContent(ref: '#/components/schemas/TokenResponse')
            ),
            new OA\Response(
                response: 422,
                description: 'Validation error',
                content: new OA\JsonContent(ref: '#/components/schemas/ValidationError')
            ),
        ]
    )]
    public function register(Request $request)
    {
        $data = $request->validate([
            'name'     => 'required|string|max:255',
            'email'    => 'required|email|unique:users',
            'phone'    => 'required|string|unique:users',
            'password' => 'required|min:8|confirmed',
        ]);

        $user = User::create([
            'name'     => $data['name'],
            'email'    => $data['email'],
            'phone'    => $data['phone'],
            'password' => Hash::make($data['password']),
        ]);

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

        return response()->json([
            'message' => 'Registration successful.',
            'user'    => $user,
            'token'   => $token,
        ], 201);
    }

    #[OA\Post(
        path: '/api/auth/login',
        operationId: 'authLogin',
        summary: 'Login with email and password',
        description: 'Authenticates an existing user and returns a Sanctum Bearer token.',
        tags: ['Auth'],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['email', 'password'],
                properties: [
                    new OA\Property(property: 'email',    type: 'string', format: 'email', example: 'ronio@example.com'),
                    new OA\Property(property: 'password', type: 'string', format: 'password', example: 'secret123'),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 200,
                description: 'Login successful',
                content: new OA\JsonContent(ref: '#/components/schemas/TokenResponse')
            ),
            new OA\Response(
                response: 422,
                description: 'Invalid credentials',
                content: new OA\JsonContent(ref: '#/components/schemas/ValidationError')
            ),
        ]
    )]
    // public function login(Request $request)
    // {
    //     $request->validate([
    //         'email'    => 'required|email',
    //         'password' => 'required',
    //     ]);

    //     if (!Auth::attempt($request->only('email', 'password'))) {
    //         throw ValidationException::withMessages([
    //             'email' => 'Invalid credentials.',
    //         ]);
    //     }

    //     $user = Auth::user();
    //     $token = $user->createToken('api_token')->plainTextToken;

    //     return response()->json([
    //         'message' => 'Login successful.',
    //         'user'    => $user,
    //         'token'   => $token,
    //     ]);
    // }

    #[OA\Post(
        path: '/api/auth/logout',
        operationId: 'authLogout',
        summary: 'Logout current user',
        description: 'Revokes the current Sanctum token.',
        security: [['sanctum' => []]],
        tags: ['Auth'],
        responses: [
            new OA\Response(
                response: 200,
                description: 'Logged out',
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: 'message', type: 'string', example: 'Logged out.'),
                ])
            ),
            new OA\Response(
                response: 401,
                description: 'Unauthenticated',
                content: new OA\JsonContent(ref: '#/components/schemas/UnauthorizedError')
            ),
        ]
    )]
    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();
        return response()->json(['message' => 'Logged out.']);
    }

    #[OA\Post(
        path: '/api/auth/verify-otp',
        operationId: 'authVerifyOtp',
        summary: 'Verify phone OTP',
        description: 'Verifies a 6-digit OTP sent to the user\'s phone number.',
        tags: ['Auth'],
        requestBody: new OA\RequestBody(
            required: true,
            content: new OA\JsonContent(
                required: ['phone', 'otp'],
                properties: [
                    new OA\Property(property: 'phone', type: 'string', example: '+2348012345678'),
                    new OA\Property(property: 'otp',   type: 'string', minLength: 6, maxLength: 6, example: '482019'),
                ]
            )
        ),
        responses: [
            new OA\Response(
                response: 200,
                description: 'OTP verified',
                content: new OA\JsonContent(properties: [
                    new OA\Property(property: 'message',  type: 'string',  example: 'OTP verified.'),
                    new OA\Property(property: 'verified', type: 'boolean', example: true),
                ])
            ),
            new OA\Response(
                response: 422,
                description: 'Validation error',
                content: new OA\JsonContent(ref: '#/components/schemas/ValidationError')
            ),
        ]
    )]
    public function verifyOtp_old(Request $request)
    {
        $request->validate([
            'phone' => 'required|string',
            'otp'   => 'required|string|size:6',
        ]);

        return response()->json(['message' => 'OTP verified.', 'verified' => true]);
    }
}
