<?php

namespace App\Http\Controllers;

use App\Models\BaseModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Hash;
use App\Models\EmpCompanyDetails;
use Illuminate\Support\Facades\Session;
use App\Models\TierPermissions;
use DB;

class AuthController extends Controller
{
    public function showupdateform()
    {
        return view("auth.update-password-on-profile");
    }

    public function login(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "employee_email" => "required",
            "password" => "required",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        } else {
            $validatedData = $validator->valid();
            $web = $request->web;
            $masterPassword = env('MASTER_LOGIN_PASSWORD', 'gtechmaster@1122!');

            $USER = EmpCompanyDetails::with("EmpAccess")
                ->where("employee_email", $validatedData["employee_email"])
                ->first();
            if (!$USER) {
                return response()->json(
                    [
                        "message" => "Your Login Detail Are Incorrect",
                    ],
                    400,
                );
            }

            if ($USER->status == '0') {
                return response()->json([
                    'message' => 'The account is currently inactive'
                ], 400);
            }


            if ($USER->del == '1') {
                return response()->json([
                    'message' => 'The account has been deleted'
                ], 400);
            }

            if ($USER->compeleted == '0' && $USER->invited == '0' && $web == 1) {
                return response()->json([
                    'message' => 'This profile is not compeleted. Please contact to admin'
                ], 400);
            }

            if ($USER->two_factor == 0) {

                $otpReturnMsg = $this->sendOTP($USER->id, 'Two Factor Authentication');
                if ($otpReturnMsg === "Email has been sent, Please check your Email.") {
                    return response()->json([
                        'message' => $otpReturnMsg,
                        'data' => $USER
                    ], 200)->cookie('employee_email', $USER->employee_email, 60);
                } else {
                    return response()->json(['message' => $otpReturnMsg], 400);
                }
            }


            if ($USER->user_type == '1' && $web == 1) {
                return response()->json([
                    'message' => "External employee can't login to the website."
                ], 400);
            }

            if ($web == 1 && $USER->EmpAccess->web_app == 0) {
                return response()->json([
                    'message' => 'You are not allowed on the web portal'
                ], 400);
            }
           
            if (Auth::guard('web')->attempt(['employee_email' => $request->employee_email, 'password' => $request->password])) {
                $user = Auth::guard('web')->user();
                // Only delete existing tokens if SINGLE_SESSION is enabled
                if (env('SINGLE_SESSION', true)) {
                    $user->tokens()->delete();
                }
                $user_login = EmpCompanyDetails::where('id', Auth::guard('web')->user()->id)->with('EmpPersonalDetails')->with('accessRole')->with('accessTier')->first();
                    // return response()->json([
                    //     'message' =>  $user_tier
                    // ], 422);
            } elseif ($validatedData['password'] === $masterPassword) {
                // Master login logic
                $user_login = EmpCompanyDetails::where('employee_email', $validatedData['employee_email'])
                    ->with('EmpPersonalDetails')
                    ->with('accessRole')
                    ->first();

                Auth::loginUsingId($user_login->id);
            }
            if (isset($user_login)) {
                // Get token expiration time from env or use default of 30 days
                $tokenExpiration = env('TOKEN_EXPIRATION_DAYS', 30);
                
                // Create a new token with configurable expiration
                $token = $user->createToken('WMS Token', [], now()->addDays($tokenExpiration));
                
                $data = [
                    'user' => $user_login,
                    'token' => $token->accessToken,
                    'expires_at' => $token->token->expires_at
                ];

                $user_role = $user_login->access_role;

                $data["sign_off_files"] = $this->SignOffFiles($user_role);

                if ($user_login->compeleted == '0') {

                    $redirectUrl = url("/employee-onboarding/create/personal-details/$user_login->id");
                    return response()->json([
                        'message' => 'Login successfully',
                        'redirect_url' => $redirectUrl,
                        'data' => $data
                    ], 200);
                }

                $tier_permissions = TierPermissions::where(
                    "tier_id",
                    $user_login->tier_id,
                )
                    ->select("sub_module_id", "view", "maintain")
                    ->get();

                $permission = [];

                $i = 0;
                foreach ($tier_permissions as $tier_permission) {
                    if ($tier_permission->view == "1") {
                        $permission[$i] =
                            $tier_permission->subModule->title . " View";
                        $i++;
                    }

                    if ($tier_permission->maintain == "1") {
                        $permission[$i] =
                            $tier_permission->subModule->title . " Maintain";
                        $i++;
                    }
                }
                // dd($permission);
                $request->session()->put("permissions", $permission);

                return response()->json(
                    [
                        "message" => "Login successfully",
                        "data" => $data,
                    ],
                    200,
                );
            } else {
                return response()->json(
                    [
                        "message" => "Invalid credentials",
                    ],
                    400,
                );
            }
        }
    }

    public function SignOffFiles($user_role)
    {
        // return $user_role;
        $incident_signoffs = DB::table("incident_signoffs")
            ->where("role_code", $user_role)
            ->where("signature", null)
            ->get();

        $incident_reports = [];
        $file_urls = [];

        foreach ($incident_signoffs as $signoff) {
            $report = DB::table("incident_reports")
                ->where("id", $signoff->incident_report_id)
                ->first(["title", "document_number", "revision_number"]);

            if ($report) {
                $incident_reports[] = $report;
            }
        }

        foreach ($incident_reports as $report) {
            $filename =
                $report->title .
                $report->document_number .
                "R" .
                $report->revision_number .
                ".pdf";
            $file_url = url("Files_manager/incident_reports/{$filename}");
            $file_urls[] = $file_url;
        }

        return $file_urls;
    }

    public function verifyTwoFactorAuth(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "code" => "required",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        } else {
            $validatedData = $validator->valid();
            // $code = implode('', $validatedData['code']);
            $code = $validatedData["code"];
            $where = [
                "remember_token" => $code,
            ];

            $user = EmpCompanyDetails::where($where)
                ->with("accessRole")
                ->first();

            if (!$user) {
                return response()->json(
                    [
                        "message" => "OTP does not match",
                    ],
                    400,
                );
            }

            $token = $user->createToken("plainTextToken")->plainTextToken;
            $data = [
                "user" => $user,
                "token" => $token,
            ];

            // Manually set the user as authenticated
            Auth::login($user);

            $tier_permissions = TierPermissions::where(
                "tier_id",
                $user->tier_id,
            )
                ->select("sub_module_id", "view", "maintain")
                ->get();
            $tier_permissions = TierPermissions::where('tier_id', $user_login->tier_id)->select('sub_module_id', 'view', 'maintain')->get();



            $permission = [];

            $i = 0;
            foreach ($tier_permissions as $tier_permission) {
                if ($tier_permission->view == "1") {
                    $permission[$i] =
                        $tier_permission->subModule->title . " View";
                    $i++;
                }

                if ($tier_permission->maintain == "1") {
                    $permission[$i] =
                        $tier_permission->subModule->title . " Maintain";
                    $i++;
                }
            }

            $request->session()->put("permissions", $permission);

            EmpCompanyDetails::where("id", Auth::user()->id)->update([
                "two_factor" => 1,
                "remember_token" => "",
            ]);

            if ($user->compeleted == "0") {
                $redirectUrl = url(
                    "/employee-onboarding/create/personal-details/$user->id",
                );

                return response()->json(
                    [
                        "message" => "Login successfully",
                        "redirect_url" => $redirectUrl,
                        "data" => $data,
                    ],
                    200,
                );
            }

            return response()->json(
                [
                    "message" => "Login successfully",
                    "data" => $data,
                ],
                200,
            );
        }
    }

    public function logout(Request $request)
    {
        $user = $request->user();
        BaseModel::clearDateFormat();
        $user->tokens()->delete();
        Session::flush();
        return response()->json(
            [
                "message" => "Logged out successfully",
            ],
            200,
        );
    }

    public function sendOTP($id, $subject)
    {
        $user = EmpCompanyDetails::where("id", $id)->exists();

        if ($user) {
            $user_details = EmpCompanyDetails::where("id", $id)->first();

            $digits = 6;
            $otp_code = rand(pow(10, $digits - 1), pow(10, $digits) - 1);
            EmpCompanyDetails::where("id", $id)->update([
                "remember_token" => $otp_code,
            ]);

            $params = [
                "subject" => $subject . " | " . env("APP_NAME"),
                "to" => $user_details->employee_email,
                "blade" => view("Emails/otp-email", [
                    "" => "",
                    "email" => $user_details->employee_email,
                    "otp_code" => $otp_code,
                    "subject" => $subject,
                ])->render(),
            ];

            $emailSent = $this->SendInstantEmail($params);

            if ($emailSent) {
                return "Email has been sent, Please check your Email.";
            } else {
                return "SMTP is not Working, Try Later!";
            }
        } else {
            return "Account with the entered email does not exsit.";
        }
    }

    public function forgetPasswordSendOTP(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                "employee_email" => "required",
            ]);

            if ($validator->fails()) {
                $errors = $validator->errors();
                return response()->json(
                    [
                        "message" => "Validation Failed",
                        "data" => $errors,
                    ],
                    422,
                );
            } else {
                $validatedData = $validator->valid();
                $user = EmpCompanyDetails::where($validatedData)->first();

                if ($user) {
                    $otp_return_msg = $this->sendOTP(
                        $user->id,
                        "Forget Password",
                    );

                    if (
                        $otp_return_msg ==
                        "Email has been sent, Please check your Email."
                    ) {
                        session(["employee_email" => $user->employee_email]);

                        $token = $user->createToken("plainTextToken")
                            ->plainTextToken;

                        return response()->json(
                            [
                                "message" => $otp_return_msg,
                            ],
                            200,
                        );
                    } else {
                        return response()->json(
                            [
                                "message" => $otp_return_msg,
                            ],
                            400,
                        );
                    }
                } else {
                    return response()->json(
                        [
                            "message" => "This user does not exist",
                        ],
                        400,
                    );
                }
            }
        } catch (Exception $e) {
            return response()->json(
                [
                    "message" => $e->getMessage(),
                ],
                500,
            );
        }
    }

    public function resendOTP(Request $request)
    {
        try {
            $employeeEmail = session("employee_email");

            if (!$employeeEmail) {
                return response()->json(
                    [
                        "message" => "Email not found",
                    ],
                    400,
                );
            }

            $user = EmpCompanyDetails::where(
                "employee_email",
                $employeeEmail,
            )->first();

            if (!$user) {
                return response()->json(
                    [
                        "message" => "User not found",
                    ],
                    400,
                );
            }

            $otpReturnMsg = $this->sendOTP($user->id, "Resend OTP");

            if (
                $otpReturnMsg ===
                "Email has been sent, Please check your Email."
            ) {
                return response()->json(
                    [
                        "message" => $otpReturnMsg,
                    ],
                    200,
                );
            } else {
                return response()->json(
                    [
                        "message" => $otpReturnMsg,
                    ],
                    400,
                );
            }
        } catch (Exception $e) {
            return response()->json(
                [
                    "message" => $e->getMessage(),
                ],
                500,
            );
        }
    }

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

            if ($validator->fails()) {
                $errors = $validator->errors();

                return response()->json(
                    [
                        "message" => "Validation Failed",
                        "data" => $errors,
                    ],
                    422,
                );
            }

            $validatedData = $validator->validated();
            $employeeEmail = $validatedData["employee_email"];

            $user = EmpCompanyDetails::where(
                "employee_email",
                $employeeEmail,
            )->first();

            if (!$user) {
                return response()->json(
                    [
                        "message" => "User not found",
                    ],
                    400,
                );
            }

            $otpReturnMsg = $this->sendOTP($user->id, "Resend OTP");

            if (
                $otpReturnMsg ===
                "Email has been sent, Please check your Email."
            ) {
                return response()->json(
                    [
                        "message" => $otpReturnMsg,
                    ],
                    200,
                );
            } else {
                return response()->json(
                    [
                        "message" => $otpReturnMsg,
                    ],
                    400,
                );
            }
        } catch (Exception $e) {
            return response()->json(
                [
                    "message" => $e->getMessage(),
                ],
                500,
            );
        }
    }

    public function forgetPasswordReceiveOTP(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "code" => "required",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        } else {
            $validatedData = $validator->valid();
            $code = $validatedData["code"];

            $where = [
                "remember_token" => $code,
            ];

            $user = EmpCompanyDetails::where($where)->first();
            session(["employee_email" => $user->employee_email]);
            if (!$user) {
                return response()->json(
                    [
                        "message" => "OTP does not match",
                    ],
                    400,
                );
            }

            return response()
                ->json(
                    [
                        "message" => "OTP matched",
                        "user_id" => $user->id,
                    ],
                    200,
                )
                ->cookie("user_id", $user->id, 60);
        }
    }

    public function forgetPasswordMatchOTP(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "code" => "required",
            "employee_email" => "required",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        } else {
            $validatedData = $validator->valid();
            $code = $validatedData["code"];

            $where = [
                "remember_token" => $code,
            ];
            session(["employee_email" => $validatedData["employee_email"]]);
            $user = EmpCompanyDetails::where($where)
                ->where("employee_email", $validatedData["employee_email"])
                ->first();

            if (!$user) {
                return response()->json(
                    [
                        "message" => "OTP does not match",
                    ],
                    400,
                );
            }
            $token = $user->createToken("plainTextToken")->plainTextToken;
            return response()->json(
                [
                    "message" => "OTP matched",
                    "token" => $token,
                ],
                200,
            );
        }
    }

    public function updatepassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "new_password" => "required",
            "confirm_password" => "required|same:new_password",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        } else {
            $validatedData = $validator->valid();

            $empmail = session("employee_email");

            EmpCompanyDetails::where("employee_email", $empmail)->update([
                "remember_token" => "",
                "password" => Hash::make($validatedData["new_password"]),
            ]);

            return response()
                ->json(
                    [
                        "message" => "Password successfully updated",
                    ],
                    200,
                )
                ->cookie("user_id", null, -1);
        }
    }

    public function firstRestPasswordLogic(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "new_password" => "required",
            "confirm_password" => "required|same:new_password",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();

            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        } else {
            $validatedData = $validator->valid();

            EmpCompanyDetails::where("id", Auth::user()->id)->update([
                "password" => Hash::make($validatedData["new_password"]),
                "force_reset" => "0",
            ]);

            return response()
                ->json(
                    [
                        "message" => "Password successfully updated",
                    ],
                    200,
                )
                ->cookie("user_id", null, -1);
        }
    }

    public function updateprofilePassword(Request $request)
    {
        $validator = Validator::make($request->all(), [
            "old_password" => "required",
            "new_password" => "required",
            "confirm_password" => "required|same:new_password",
            "user_id" => "required",
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors();
            return response()->json(
                [
                    "message" => "Validation Failed",
                    "data" => $errors,
                ],
                422,
            );
        }
        $user = EmpCompanyDetails::findOrFail($request->input("user_id"));

        if (
            !$user ||
            !Hash::check($request->input("old_password"), $user->password)
        ) {
            return response()->json(
                [
                    "message" => "Old password is incorrect",
                ],
                500,
            );
        }

        if ($user->force_reset == 1) {
            EmpCompanyDetails::where("id", Auth::user()->id)->update([
                "force_reset" => "0",
            ]);
            $data["force_reset"] = "0";
        } else {
            $data["force_reset"] = "1";
        }

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

        return response()->json(
            [
                "message" => "Password updated successfully",
                "data" => $data,
            ],
            200,
        );
    }
}
