<?php

namespace Modules\Linksehat\Http\Controllers\Api;

use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Models\Person;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Laravel\Socialite\Facades\Socialite;
use Modules\Linksehat\Transformers\UserProfileResource;
use Symfony\Component\HttpFoundation\Response;
use Validator;

class AuthController extends Controller
{
    public function otpRequest(Request $request)
    {
        $request->validate([
            // 'phone' => 'required'
            'phone_or_email' => 'required'
        ]);

        if (filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL)) {
            $user = User::updateOrCreate([
                'email' => $request->phone_or_email
            ], [
                'email' => $request->phone_or_email,
                'otp' => rand(1000, 9999),
                'otp_created_at' => now()
            ]);

            $person = Person::query()->create([
                'owner_user_id' => $user->id,
                'email' => $request->phone_or_email,
                'created_by' => $user->id,
            ]);

            User::query()->find($user->id)->update([
                'person_id' => $person->id
            ]);
        } else {
            $user = User::updateOrCreate([
                'phone' => $request->phone_or_email
            ], [
                'phone' => $request->phone_or_email,
                'otp' => rand(1000, 9999),
                'otp_created_at' => now()
            ]);

            $person = Person::query()->create([
                'owner_user_id' => $user->id,
                'phone' => $request->phone_or_email,
                'created_by' => $user->id,
            ]);

            User::query()->find($user->id)->update([
                'person_id' => $person->id
            ]);
        }

        if (!$user) {
            $message = filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL) ? "User dengan alamat email " . $request->phone_or_email . " tidak ditemukan" : "User dengan nomor telepon " . $request->phone_or_email . " tidak ditemukan";

            return Helper::responseJson(statusCode: Response::HTTP_NOT_FOUND, message: $message);
        }

        // TODO Send the OTP
        if (filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL)) {
            // Send Email
        } else {
            // Send Whatsapp
        }

        return Helper::responseJson(message: 'OTP Terkirim');
    }

    public function login(Request $request)
    {
        $request->validate([
            // 'email' => 'email',
            // 'password' => 'required_with:email',
            // 'phone' => '',
            // 'otp' => 'required_with:phone',
            'phone_or_email' => 'required',
            'otp' => 'required'
        ]);

        $loginType = filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';

        if ($loginType == 'email') {
            $user = User::query()
                ->where('email', $request->phone_or_email)
                ->first();
        }

        if ($loginType == 'phone') {
            $user = User::query()
                ->where('phone', $request->phone_or_email)
                ->first();
        }

        if (!isset($user) || empty($user)) {
            return response(['message' => 'User Tidak Ditemukan'], 404);
        }

        if ($loginType == 'email') {
            if ($request->otp != $user->otp) {
                return response(['message' => 'OTP Salah, Silahkan Cek Kembali Email Anda'], 403);
            }
        } else if ($loginType == 'phone') {
            if ($request->otp != $user->otp) {
                return response(['message' => 'OTP Salah'], 403);
            }
        } else {
            return response(['message' => 'Mode Login Tidak Dikenal'], 403);
        }

        return Helper::responseJson(
            data: [
                'token' => $user->createToken('app')->plainTextToken,
                'user' => UserProfileResource::make($user),
            ],
            message: 'Selamat Datang'
        );
    }

    public function register(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'email' => 'required|email|unique:users,email',
            'password' => [
                'required',
                'confirmed',
                'min:8',
                'regex:/.*[0-9].*/',
                'regex:/.*[a-z].*/',
                'regex:/.*[A-Z].*/',
            ]
        ], [
            'password.regex' => "Password harus minimal 8 karakter, kombinasi huruf besar kecil dan angka"
        ])->validate();

        try {
            User::create([
                'email' => $request->email,
                'password' => Hash::make($request->password),
            ]);

            return Helper::responseJson(statusCode: Response::HTTP_CREATED, message: 'Akun berhasil dibuat, silahkan cek E-mail untuk konfirmasi');
        } catch (\Exception $e) {
            return Helper::responseJson(['error_message' => $e->getMessage()], Response::HTTP_FORBIDDEN, 'Terjadi masalah ketika mendaftar');
        }
    }

    public function logout(Request $request)
    {
        $token = $request->bearerToken();
        Auth::user()->tokens()->where('id', $token)->delete();

        return Helper::responseJson(message: 'Behasil Logout.');
    }

    public function mockOtp(Request $request)
    {
        $request->validate([
            'phone_or_email' => 'required'
        ]);

        $user = User::query()->where((filter_var($request->phone_or_email, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone'), $request->phone_or_email)->firstOrFail();

        return Helper::responseJson(data: [
            'otp' => $user->otp,
            'otp_valid_until' => $user->otp_created_at ? $user->otp_created_at->addMinutes(config('linksehat.otp_valid_minutes')) : null
        ], message: 'OTP Anda');
    }

    public function redirectSocialLogin($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    public function handleSocialLoginCallback($provider)
    {
        $providerUser = Socialite::driver($provider)->stateless()->user();
        $user = User::query()->firstWhere('email', $providerUser->email);

        if (!$user) {
            $user = User::query()->create([
                'email' => $providerUser->email,
            ]);

            $person = Person::query()->create([
                'owner_user_id' => $user->id,
                'name' => $providerUser->name,
                'email' => $providerUser->email,
                'created_by' => $user->id,
            ]);

            User::query()->find($user->id)->update([
                'person_id' => $person->id
            ]);
        }

        return Helper::responseJson(data: [
            'user' => UserProfileResource::make($user),
            'token' => $user->createToken('app')->plainTextToken
        ], message: 'Selamat Datang');
    }
}
