<?php

namespace App\Http\Controllers;

use App\Models\Customers;
use App\Models\CustomersPlans;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    private function getCustomerId(Request $request)
    {
        $token = $request->bearerToken();

        if (!$token) {
            return response()->json([
                'success' => false,
                'message' => 'Missing auth token'
            ], 401);
        }

        try {
            return Crypt::decrypt($token);
        } catch (\Throwable $e) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid auth token'
            ], 401);
        }
    }

    public function signup(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'first_name'        => 'required|string|max:255',
                // 'phone'            => 'required|string|unique:customers,phone',
                'email'             => 'required|email|unique:customers,email',
                'password'          => 'required|min:6',
                'confirm_password'  => 'required|same:password',
                'terms'             => 'accepted',
            ], [
                'first_name.required' => 'First name is required.',
                'first_name.string'   => 'First name must be a valid string.',
                'first_name.max'      => 'First name cannot exceed 255 characters.',

                // 'phone.required'     => 'Phone number is required.',
                // 'phone.string'       => 'Phone number must be string.',
                // 'phone.unique'       => 'Phone number is already taken.',

                'email.required'      => 'E-Mail is required.',
                'email.email'         => 'E-Mail must be a valid email address.',
                'email.unique'        => 'E-Mail is already taken.',

                'password.required'   => 'Password is required.',
                'password.min'        => 'Password must be at least 6 characters.',

                'confirm_password.required' => 'Confirm Password is required.',
                'confirm_password.same'     => 'Passwords do not match.',

                'terms.accepted'      => 'You must accept the terms.',
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'message' => $validator->errors()->first(),
                    'errors'  => $validator->errors() // optional: return all errors
                ], 422);
            }

            $check_customer = Customers::where('email', $request->email)->count();
            if ($check_customer > 0) {
                return response()->json(['status' => 'error', 'message' => 'You are already registered, please verify yourself!'], 400);
            }

            $customer_order = Customers::max('position_order');
            $position_order = ($customer_order !== null) ? $customer_order + 1 : 1;

            $customer = new Customers();
            $customer->position_order = $position_order;
            $customer->first_name = $request->first_name;
            $customer->last_name = $request->last_name;
            // $customer->phone = $request->phone;
            $customer->email = $request->email;
            $customer->password = Hash::make($request->password);
            $customer->terms = $request->terms;
            $customer->save();

            // $token = $customer->createToken('customer-token')->plainTextToken;
            $token = Crypt::encrypt($customer->id);

            return response()->json([
                'status' => 'success',
                'message' => 'Signup Successful!',
                'access_token' => $token,
                'customer' => $customer,
            ], 201);
        } catch (ValidationException $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422);
        }
    }

    public function login(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|email',
                'password' => 'required|string',
            ], [
                'email.required'      => 'Email is required.',
                'email.email'         => 'Email must be a valid email address.',

                'password.required'   => 'Password is required.',
                'password.string'     => 'Password must be in string format.',
            ]);

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

            $customer = Customers::where('email', $request->email)->first();

            if (!$customer) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'You are not registered, please make an account!',
                ], 401); // Unauthorized
            }

            if ($customer->status == 'deactive') {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Please verify your account to login, contact to Administrator!',
                ], 401); // Unauthorized
            }

            if (!Hash::check($request->password, $customer->password)) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Invalid credentials',
                ], 401); // Unauthorized
            }

            $customer_active_plan = null;
            if ($customer->active_plan_id != 0) {
                $customer_active_plan = CustomersPlans::with([
                    'plan:id,plan_name,plan_price,plan_price_base,plan_storage_limit'
                ])
                    ->select('id', 'plan_status', 'start_date', 'expiry_date', 'plan_id')
                    ->where([
                        'customer_id' => $customer->id,
                        'plan_id' => $customer->active_plan_id,
                    ])
                    ->first();
            }

            $token = Crypt::encrypt($customer->id);

            return response()->json([
                'status' => 'success',
                'access_token' => $token,
                'token_type' => 'Bearer',
                'customer' => $customer,
                'active_plan' => $customer_active_plan,
            ], 200); // OK

        } catch (ValidationException $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Validation failed',
                'errors' => $e->errors()
            ], 422); // Unprocessable Entity
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Something went wrong',
            ], 500); // Internal Server Error
        }
    }

    public function getAndUpdateCustomerProfile(Request $request)
    {
        try {
            $enc_token = $request->bearerToken();
            if (!$enc_token) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Missing auth token'
                ], 401);
            }

            $customer_id = Crypt::decrypt($enc_token);
            $customer = Customers::find($customer_id);

            if (!$customer) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Data not found!',
                ], 404);
            }

            // ---------------------------------------------------
            // 🔁 UPDATE MODE (POST / PUT)
            // ---------------------------------------------------
            if ($request->isMethod('post') || $request->isMethod('put')) {

                $validated = $request->validate([
                    'first_name'     => 'required|string|max:255',
                    'last_name'      => 'nullable|string|max:255',
                    'email'          => 'required|email|max:255',
                    'phone'          => 'required|string|max:20',
                    'profile_photo'  => 'nullable|image|mimes:jpg,jpeg,png,webp|max:2048',
                ]);

                // Update basic fields
                $customer->first_name = $validated['first_name'];
                $customer->last_name  = $validated['last_name'];
                $customer->email      = $validated['email'];
                $customer->phone      = $validated['phone'];

                // Handle photo upload
                if ($request->hasFile('profile_photo')) {
                    $path = 'images/customers/';
                    $filePath = $this->storeImage($request->file('profile_photo'), $path, $customer->profile_photo);
                    $customer->profile_photo = $filePath;
                }

                $customer->save();

                return response()->json([
                    'status'  => 'success',
                    'message' => 'Profile updated successfully!',
                    'customer' => [
                        'first_name' => $customer->first_name,
                        'last_name'  => $customer->last_name,
                        'phone'      => $customer->phone,
                        'email'      => $customer->email,
                        'profile_photo' => asset($customer->profile_photo),
                    ],
                ], 200);
            }

            // ---------------------------------------------------
            // 📥 GET MODE (default)
            // ---------------------------------------------------
            $customer_data = [
                'first_name' => $customer->first_name,
                'last_name'  => $customer->last_name,
                'phone'      => $customer->phone,
                'email'      => $customer->email,
                'profile_photo' => asset($customer->profile_photo),
            ];

            return response()->json([
                'status'   => 'success',
                'customer' => $customer_data,
            ], 200);
        } catch (ValidationException $e) {
            return response()->json([
                'status'  => 'error',
                'message' => 'Validation failed',
                'errors'  => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            Log::error("Profile Error: " . $e->getMessage());

            return response()->json([
                'status'  => 'error',
                'message' => 'Something went wrong',
            ], 500);
        }
    }

    public function checkEmailAndSendLink(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|email'
            ]);

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

            $customer = Customers::where('email', $request->email)->where('status', 'active')->first();

            if (!$customer) {
                return response()->json([
                    'message' => 'Account not found, please register or verify yourself.',
                ], 404);
            }

            $status = Password::broker('customer')->sendResetLink(
                $request->only('email')
            );

            if ($status === Password::RESET_LINK_SENT) {
                return response()->json([
                    'message' => 'A reset link has been sent to your E-Mail address. Please check your inbox.',
                ], 200);
            }

            return response()->json([
                'message' => 'Failed to send reset link. Please try again later.',
            ], 500);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'An unexpected error occurred.',
                'error'   => $e->getMessage(),
            ], 500);
        }
    }

    public function checkResetLink(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|email',
                'token' => 'required|string'
            ]);

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

            $customer = Customers::where('email', $request->email)->where('status', 'active')->first();

            if (!$customer) {
                return response()->json([
                    'message' => 'Invalid reset link. Please request a new one.',
                ], 404);
            }

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

            if (!$record || !Hash::check($request->token, $record->token)) {
                return response()->json([
                    'message' => 'Invalid or expired reset link.',
                ], 404);
            }

            // Optional: check token expiration (10 minutes)
            if (Carbon::parse($record->created_at)->addMinutes(10)->isPast()) {
                return response()->json([
                    'message' => 'Reset link has expired. Please request a new one.',
                ], 404);
            }

            return response()->json([
                'message' => 'Reset link is valid.',
            ], 200);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'An unexpected error occurred while verifying the link.',
                'error'   => $e->getMessage(),
            ], 500);
        }
    }

    public function resetPassword(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'email' => 'required|email',
                'token' => 'required|string',
                'password' => 'required|string|min:6|confirmed', // expects password_confirmation
            ]);

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

            $current_customer = Customers::where('email', $request->email)->where('status', 'active')->first();

            if (!$current_customer) {
                return response()->json([
                    'message' => 'Account is not registered or verified. Please register or verify yourself!',
                ], 404);
            }

            $status = Password::broker('customer')->reset(
                $request->only('email', 'password', 'password_confirmation', 'token'),
                function ($customer, $password) {
                    $customer->password = Hash::make($password);
                    $customer->save();

                    $customer->setRememberToken(Str::random(60));
                    $customer->save();
                }
            );

            if ($status === Password::PASSWORD_RESET) {
                return response()->json([
                    'message' => 'Password has been reset successfully.',
                ], 200);
            }

            return response()->json([
                'message' => $status === Password::INVALID_TOKEN
                    ? 'This reset link has already been used or expired. Please request a new one.'
                    : __($status),
            ], 400);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'An unexpected error occurred.',
                'error'   => $e->getMessage(),
            ], 500);
        }
    }

    public function updateCustomerPassword(Request $request)
    {
        $customer_id = $this->getCustomerId($request);
        if ($customer_id instanceof \Illuminate\Http\JsonResponse) {
            return $customer_id;
        }

        // return response()->json([
        //     'status' => false,
        //     'errors' => $request->all()
        // ], 422);

        try {
            $request->validate([
                'current_password' => 'required',
                'new_password' => [
                    'required',
                    'string',
                    'min:8',
                    'regex:/[A-Z]/',
                    'regex:/[a-z]/',
                    'regex:/[0-9]/',
                    'regex:/[^A-Za-z0-9]/',
                    'confirmed'
                ],
            ], [
                'new_password.regex' =>
                'Password must contain uppercase, lowercase, number and special character.',
            ]);

            $customer = Customers::findOrFail($customer_id);

            // Current password incorrect
            if (!Hash::check($request->current_password, $customer->password)) {
                return response()->json([
                    'status' => false,
                    'message' => 'Current password is incorrect.'
                ], 422);
            }

            // Update password
            $customer->password = Hash::make($request->new_password);
            $customer->save();

            return response()->json([
                'status' => true,
                'message' => 'Password updated successfully.'
            ]);
        } catch (ValidationException $e) {
            Log::error('Validation failed', ['error' => $e->getMessage()]);

            return response()->json([
                'status' => false,
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            Log::error('Password update failed', ['error' => $e->getMessage()]);

            return response()->json([
                'status' => false,
                'message' => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }
}
