package org.example.Auth.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.example.Api.BaseHandler;
import org.example.Api.OptBaseHandler;
import org.example.Entity.Attributes.RequestCheck;
import org.example.Entity.Attributes.RequestCheckAttribute;
import org.example.Entity.BaseResponse.BaseResponse;
import org.example.Enums.SystemTypeEnums;
import org.example.Impl.BaseImpl;
import org.example.Impl.SMSImpl;
import org.example.Impl.SysUserImpl;
import org.example.Service.AuthService;
import org.example.Auth.utils.JwtUtils;
import org.example.Auth.utils.SafetyUtil;
import org.example.Entity.System.LoginUserInfo;
import org.example.Utils.DataTableUtil;
import org.example.Utils.DbOperator;
import org.example.Utils.JwtHelp;
import org.example.Utils.NativeExtensionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Objects;

import static org.example.Enums.SystemTypeEnums.LoginType.Web;
import static org.example.Utils.NativeExtensionUtils.ToInt32;

@RestController
@RequestMapping("/Api/SysUserAjaxApi")
public class AuthController extends OptBaseHandler {
    @RequestMapping(value = "/**", method = {RequestMethod.GET, RequestMethod.POST})
    public void handleRequest(HttpServletRequest Request, HttpServletResponse response) throws Exception {
        // 调用 BaseHandler 的 processRequest 处理逻辑
        super.processRequest(Request);
    }

    @Autowired
    private AuthService authService;

    @Autowired
    SysUserImpl userOperator;

    protected void InitSystemParams(HttpServletRequest ctx) {
        super.initSystemParams(ctx);
    }


    @RequestCheck(
            CheckLogin = false,  // 登录不需要先登录
            CheckParams = "username|phone",  // 必须传递username或phone
            Log = true  // 打印日志
    )
    //对应c#的login
    public void Login() {
        BaseImpl bImpl = getBImpl();
        String loginAccount = bImpl.Request("username"), pwd = bImpl.Request("password"), phone = bImpl.Request("phone"), phonecode = bImpl.Request("phonecode"), seriesId = bImpl.Request("seriesId"), serverId = bImpl.Request("server"), gtClientInfo = bImpl.Request("OsClientInfo");
        // 1. 优先走「手机号+验证码」登录（与 C# 分支逻辑一致）
        if (!NativeExtensionUtils.isNullOrEmpty(phone) && !NativeExtensionUtils.isNullOrEmpty(phonecode)) {
            // 调用手机号登录方法（需确保 AuthService 有此方法，参数匹配）
            response = userOperator.LoginByPhone(phone, phonecode,loginAccount,null);
        }
        // 2. 其次走「账号+密码」登录（C# 中固定 LoginType.Web，IP 传 null）
        else if (!NativeExtensionUtils.isNullOrEmpty(loginAccount)) {
            // 参数对应 C#：loginAccount, pwd, seriesId, serverId.ToInt32(), LoginType.Web, null, gtClientInfo
            response = userOperator.Login(
                    loginAccount,
                    pwd,
                    seriesId,
                    ToInt32(serverId),
                    Web, // 与 C# LoginType.Web 对齐，需确保枚举值存在
                    null, // C# 中此参数传 null，对应 Java 接口的 ip 参数
                    gtClientInfo // 对应 C# 的 gtClientInfo
            );
        }
    }

    public void ChangeServer() {
        BaseResponse[] response = new BaseResponse[1];
        response[0] = new BaseResponse();
        BaseImpl bImpl = getBImpl();
        int serverId = ToInt32(bImpl.Request("server"));
        StringBuilder errMsg;
        errMsg = new StringBuilder();
        DbOperator dbOper = userOperator.ChangeServer(serverId, errMsg);
        if (dbOper != null && serverId != getUser().ServerId) {
            bImpl.sysLog(String.format("{0}切换账套{1}=>{2}", getUser().UserName, getUser().ServerId, serverId), "切换账套");
            getUser().ConnectionString = dbOper.getConnectionString();
            getUser().ServerId = serverId;
            LoginUserInfo _user = userOperator.OnLoginSuccess(null, getUser(), getUser().SeriesId, getUser().ServerId, getUser().UserId, dbOper.getConnectionString(), response[0], true);
            BaseImpl.setSessionVal(getUserSessionName(), _user);
            if (!NativeExtensionUtils.isNullOrEmpty(getDriver()) && (Objects.equals(getDriver(), "android") || Objects.equals(getDriver(), "ios"))) {
                response[0].setToken(JwtHelp.createToken(_user, 2592000));//过期时间30天
            } else {
                response[0].setToken(JwtHelp.createToken(_user, 3600));
                BaseImpl.setSessionVal(getUserSessionName(), _user);
            }
            response[0].setSuccess(true);
        } else {
            response[0].setMsg("切换失败:{"+errMsg+"}!");
        }
           super.response=response[0];
    }

    //对应c#的getseverName，上面的那个ChangeServer牵涉到数据库的切换，所有关于数据库切换的都没整
    public void GetServerName() {
        response.setData(userOperator.GetCurrentServerName());
        response.setSuccess(true);
    }

    @RequestCheck(CheckParams = "oldpassword|newpassword|renewpassword")
    //对应restpwd
    public void ResetPwd() {
        BaseImpl bImpl = getBImpl();
        String oldPwd = bImpl.Request("oldpassword"), newPwd = bImpl.Request("newpassword"), renewPwd = bImpl.Request("renewpassword");
        response = userOperator.ResetPwd(oldPwd, newPwd, renewPwd);
    }

    @RequestCheck(CheckParams = "newpassword|renewpassword")
    //对应restpwdcomp
    public void ResetPwdComp() {
        BaseImpl bImpl = getBImpl();
        String newPwd = bImpl.Request("newpassword"), renewPwd = bImpl.Request("renewpassword");
        response = userOperator.ResetPwdComp(newPwd, renewPwd);
    }

    //新增
    @RequestCheck(CheckParams = "newpassword|renewpassword", CheckLogin = false)
    //ResetPwdByVerify
    public void ResetPwdByVerify() {
        BaseImpl bImpl = getBImpl();
        String newPwd = bImpl.Request("newpassword"), renewPwd = bImpl.Request("renewpassword"),uuid = bImpl.Request("codeuuid");
        response = userOperator.ResetPwdCompByverify(newPwd, renewPwd,uuid);
    }


    public void InitializePwd() {
        BaseImpl bImpl = getBImpl();
        String oldPwd = bImpl.Request("username"), newPwd = bImpl.Request("newpassword"), renewPwd = bImpl.Request("renewpassword");
        response = userOperator.InitializePwd(oldPwd, newPwd, renewPwd);
    }

    /**
     * 登出接口
     * 无需请求体参数，通过请求头中的 Token 识别用户
     */
    @RequestCheck(
            CheckLogin = true,  // 登出需要先登录
            CheckParams = "",   // 不校验参数
            Log = false         // 不打印日志
    )

    public void LoginOut() {
        BaseImpl bImpl = getBImpl();
        int delay = ToInt32(bImpl.Request("delay"));
        if (delay <= 0 && bImpl.isPhone()) {
            userOperator.LoginOut();
        }
        super.loginOut();

    }

    @RequestCheck(CheckLogin = false)
    public boolean CheckLogin() {

        boolean ok = super.checkLogin();
        if (ok && getBImpl().isPhone() && getBImpl().getAppVersion() > 0) {
            userOperator.UpdOsVersion();
        }

        return ok;
    }

    @RequestCheck(CheckLogin = false)
    public void GetUserByName() {

        String LoginAccount = getBImpl().Request("username");
        response.setData(userOperator.GetUserByName(LoginAccount, ""));
        response.setSuccess(response.getData() != null);

    }

    @RequestCheck(CheckParams = "userid")
    public void GetGPSLoction() {
        BaseImpl bImpl = getBImpl();
        String userid = bImpl.Request("userid"), lasttime = bImpl.Request("lasttime");
        lasttime = NativeExtensionUtils.isNullOrEmpty(lasttime) ? LocalDate.now().atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : lasttime;

        response = userOperator.GetGPSLoction(userid, lasttime);
    }

    @RequestCheck(CheckLogin = false)
    public void GenerateCaptcha(){
        BaseImpl bImpl = getBImpl();
        String captchaCodeKey = bImpl.Request("captchaCodeKey");
        response = userOperator.GenerateCaptcha(captchaCodeKey);
    }

    @RequestCheck(CheckLogin = false)
    public void SendPhoneCode()
    {
        BaseImpl bImpl = getBImpl();
        SMSImpl sMSImpl = new SMSImpl();
        String phoneNumber= bImpl.Request("phone");
        String phonecode = bImpl.Request("phonecode");
        String imageCode = bImpl.Request("code");
        String codeKey = bImpl.Request("codekey");
        response = sMSImpl.sendPhoneCode(phoneNumber,phonecode,imageCode, codeKey);
    }
   @RequestCheck(CheckLogin = false)
    public void verifyCode()
    {
        BaseImpl bImpl = getBImpl();
        String phoneNumber = bImpl.Request("phone");
        String phoneCode = bImpl.Request("phonecode");
        String username = bImpl.Request("username");
        String uuid = bImpl.Request("codeuuid");
        response = userOperator.verifyCode(phoneNumber,phoneCode, username, uuid);
    }
@RequestCheck(CheckLogin = false)
    public void GetPhoneNumber()
    {
        BaseImpl bImpl = getBImpl();
        String username = bImpl.Request("username");
        response = userOperator.GetPhoneNumber(username);
    }
@RequestCheck(CheckLogin = false)
    public void ResetPwdByPhone()
    {
        response = userOperator.ResetPwdByPhone();
    }


}
