<?php

namespace App\Http\Controllers\Api\User;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Api\Traits\ApiResponse;
use App\Http\Requests\Api\Provider\ChangeContactDetailsRequest;
use App\Http\Requests\Api\Provider\SendVerificationCodeRequest;
use App\Http\Requests\Api\User\UpdateUserProfileRequest;
use App\Http\Resources\UserResource;
use App\Notifications\ConfirmEmailNotification;
use App\Services\SmsService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Notification;

class UserProfileController extends Controller
{
    use ApiResponse;
    public function __construct(private SmsService $smsService) {}

    /**
     * @OA\Get(
     *     path="/api/user/profile",
     *     summary="Get the authenticated user's profile",
     *     tags={"User Profile"},
     *     security={{"bearerAuth":{}}},
     *     @OA\Parameter(
     *         name="Accept-Language",
     *         in="header",
     *         required=false,
     *         description="Language preference (e.g., 'en', 'ar')",
     *         @OA\Schema(type="string", enum={"en", "ar"}, default="en")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="User profile data",
     *         @OA\JsonContent(
     *             @OA\Property(property="success", type="boolean", example=true),
     *             @OA\Property(property="data", ref="#/components/schemas/UserResource"),
     *             @OA\Property(property="message", type="string", example="Profile retrieved successfully.")
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthenticated"
     *     )
     * )
     */
    public function show()
    {
        return $this->successResponse(new UserResource(Auth::user()), __('messages.profile_retrieved_successfully'));
    }

    /**
     * @OA\Put(
     *     path="/api/user/profile",
     *     summary="Update the authenticated user's profile",
     *     tags={"User Profile"},
     *     security={{"bearerAuth":{}}},
     *     @OA\Parameter(
     *         name="Accept-Language",
     *         in="header",
     *         required=false,
     *         description="Language preference (e.g., 'en', 'ar')",
     *         @OA\Schema(type="string", enum={"en", "ar"}, default="en")
     *     ),
     *     @OA\RequestBody(
     *         required=true,
     *         @OA\JsonContent(
     *             @OA\Property(property="first_name", type="string", example="John"),
     *             @OA\Property(property="last_name", type="string", example="Doe"),
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="User profile updated successfully",
     *         @OA\JsonContent(
     *             @OA\Property(property="success", type="boolean", example=true),
     *             @OA\Property(property="data", ref="#/components/schemas/UserResource"),
     *             @OA\Property(property="message", type="string", example="Profile updated successfully.")
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthenticated"
     *     ),
     *     @OA\Response(
     *         response=422,
     *         description="Validation error"
     *     )
     * )
     */
    public function update(UpdateUserProfileRequest $request)
    {
        /** @var \App\Models\User $user */
        $user = Auth::user();
        $user->update($request->validated());

        return $this->successResponse(new UserResource($user), __('messages.profile_updated_successfully'));
    }

    /**
     * @OA\Delete(
     *     path="/api/user/profile",
     *     summary="Delete the authenticated user's account",
     *     tags={"User Profile"},
     *     security={{"bearerAuth":{}}},
     *     @OA\Parameter(
     *         name="Accept-Language",
     *         in="header",
     *         required=false,
     *         description="Language preference (e.g., 'en', 'ar')",
     *         @OA\Schema(type="string", enum={"en", "ar"}, default="en")
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Account deleted successfully",
     *         @OA\JsonContent(
     *             @OA\Property(property="success", type="boolean", example=true),
     *             @OA\Property(property="data", type="object", nullable=true),
     *             @OA\Property(property="message", type="string", example="Account deleted successfully.")
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthenticated"
     *     )
     * )
     */
    public function destroy()
    {
        /** @var \App\Models\User $user */
        $user = Auth::user();

        if ($user->upcomingBookingItems()->exists()) {
            return $this->errorResponse(__('messages.cannot_delete_account_with_upcoming_bookings'), 422);
        }

        $user->delete();

        return $this->successResponse(null, __('messages.account_deleted_successfully'));
    }

    /**
     * @OA\Post(
     *     path="/api/user/password/send-verification-code",
     *     summary="Send verification code for contact detail change",
     *     description="Sends a verification code to the new email or phone number. The code is used to verify the change in the 'Change Contact Details' endpoint.",
     *     tags={"User Profile"},
     *     security={{"bearerAuth":{}}},
     *     @OA\Parameter(
     *         name="Accept-Language",
     *         in="header",
     *         required=false,
     *         description="Language preference (e.g., 'en', 'ar')",
     *         @OA\Schema(type="string", enum={"en", "ar"}, default="en")
     *     ),
     *     @OA\RequestBody(
     *         required=true,
     *         description="Provide either the new email or new phone, but not both. The new contact detail must be unique.",
     *         @OA\JsonContent(
     *             @OA\Property(property="phone", type="string", example="9665xxxxxxx"),
     *             oneOf={
     *                 @OA\Schema(required={"email"}, @OA\Property(property="email", type="string", format="email", example="new.user@example.com")),
     *                 @OA\Schema(required={"phone"}, @OA\Property(property="phone", type="string", example="966512345679"))
     *             }
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Verification code sent successfully",
     *         @OA\JsonContent(
     *             @OA\Property(property="success", type="boolean", example=true),
     *             @OA\Property(property="data", type="object", nullable=true),
     *             @OA\Property(property="message", type="string", example="Verification code sent.")
     *         )
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthenticated"
     *     ),
     *     @OA\Response(
     *         response=422,
     *         description="Validation error"
     *     )
     * )
     */
    public function sendVerificationCode(SendVerificationCodeRequest $request)
    {

        $email = $request->input("email");
        $phone = $request->input('phone');

        $identifier = $email ?? $phone;
        $user = $request->user();

        $token = strval(rand(1000, 9999));
        if (!app()->isProduction()) {
            $token = "0000";
        }
        DB::table('password_reset_tokens')->updateOrInsert(
            ['email' => $identifier],
            [
                'token' => Hash::make($token),
                'created_at' => Carbon::now()
            ]
        );

        if ($email) {
            Notification::route('mail', $email)
                ->notify(new ConfirmEmailNotification($user->name, $email, $token));
        } elseif ($phone) {
            if (app()->isProduction())
                $this->smsService->send($user->phone, "Your OTP is: {$token}");
            // $user->notify(new ForgetPasswordSMSNotification($user->name, $user->phone, $token));
        }

        return $this->successResponse(null, __('messages.password_reset_token_sent'));
    }

    /**
     * @OA\Post(
     *     path="/api/user/profile/change-contact-details",
     *     summary="Change user's contact details",
     *     description="Updates the user's email or phone number after verifying the code received from the 'Send verification code' endpoint.",
     *     tags={"User Profile"},
     *     security={{"bearerAuth":{}}},
     *     @OA\Parameter(
     *         name="Accept-Language",
     *         in="header",
     *         required=false,
     *         description="Language preference (e.g., 'en', 'ar')",
     *         @OA\Schema(type="string", enum={"en", "ar"}, default="en")
     *     ),
     *     @OA\RequestBody(
     *         required=true,
     *         description="Provide the verification code and either the new email or new phone that the code was sent to.",
     *         @OA\JsonContent(
     *             required={"code"},
     *             @OA\Property(property="code", type="string", example="0000"),
     *             @OA\Property(property="phone", type="string", example="9665xxxxxxx"),
     *             oneOf={
     *                 @OA\Schema(required={"email"}, @OA\Property(property="email", type="string", format="email", example="new.user@example.com")),
     *                 @OA\Schema(required={"phone"}, @OA\Property(property="phone", type="string", example="966512345679"))
     *             }
     *         )
     *     ),
     *     @OA\Response(
     *         response=200,
     *         description="Contact details updated successfully",
     *         @OA\JsonContent(
     *             @OA\Property(property="success", type="boolean", example=true),
     *             @OA\Property(property="data", type="object", nullable=true),
     *             @OA\Property(property="message", type="string", example="Profile updated.")
     *         )
     *     ),
     *     @OA\Response(
     *         response=400,
     *         description="Invalid or expired token"
     *     ),
     *     @OA\Response(
     *         response=401,
     *         description="Unauthenticated"
     *     ),
     *     @OA\Response(
     *         response=422,
     *         description="Validation error"
     *     )
     * )
     */
    public function changeContactDetails(ChangeContactDetailsRequest $request)
    {
        $email = $request->input("email");
        $phone = $request->input('phone');

        $identifier = $email ?? $phone;


        $user = $request->user();

        $resetRecord = DB::table('password_reset_tokens')
            ->where('email', $identifier)
            ->first();

        if (!$resetRecord) {
            return $this->errorResponse(__('messages.invalid_token'), 400);
        }
        if (!Hash::check($request->code, $resetRecord->token)) {
            return $this->errorResponse(__('messages.invalid_token'), 400);
        }

        if (Carbon::now()->diffInMinutes($resetRecord->created_at) > 10) {
            return $this->errorResponse(__('messages.token_expired'), 400);
        }

        if ($request->has('email')) {
            $user->email = $request->email;
        }

        if ($request->has('phone')) {
            $user->phone = $request->phone;
        }

        $user->save();

        DB::table('password_reset_tokens')->where('email', $identifier)->delete();

        return $this->successResponse(UserResource::make($user), __('messages.profile_updated'));
    }
}
