package com.erp.user.controller;

import com.erp.user.dto.auth.*;
import com.erp.user.entity.auth.AuthToken;
import com.erp.user.entity.auth.LoginDevice;
import com.erp.user.exception.auth.AuthException;
import com.erp.user.security.AuthDetails;
import com.erp.user.security.JwtTokenProvider;
import com.erp.user.service.auth.*;
import com.wf.captcha.base.Captcha;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.List;
import java.util.Map;

/**
 * 认证控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
    
    private final AuthService authService;
    private final SmsService smsService;
    private final WechatService wechatService;
    private final CaptchaService captchaService;
    private final DeviceService deviceService;
    private final JwtTokenProvider jwtTokenProvider;
    
    /**
     * 账号密码登录
     */
    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@Valid @RequestBody LoginRequest request,
                                               HttpServletRequest httpRequest) {
        String ip = getClientIp(httpRequest);
        String userAgent = httpRequest.getHeader("User-Agent");
        
        AuthResponse response = authService.login(request, ip, userAgent);
        return ResponseEntity.ok(response);
    }
    
    /**
     * 注册
     */
    @PostMapping("/register")
    public ResponseEntity<AuthResponse> register(@Valid @RequestBody RegisterRequest request,
                                                  HttpServletRequest httpRequest) {
        String ip = getClientIp(httpRequest);
        String userAgent = httpRequest.getHeader("User-Agent");
        
        AuthResponse response = authService.register(request, ip, userAgent);
        return ResponseEntity.ok(response);
    }
    
    /**
     * 登出
     */
    @PostMapping("/logout")
    public ResponseEntity<Void> logout(@RequestHeader("Authorization") String authHeader) {
        String token = extractToken(authHeader);
        authService.logout(token);
        return ResponseEntity.ok().build();
    }
    
    /**
     * 刷新Token
     */
    @PostMapping("/refresh")
    public ResponseEntity<AuthResponse> refresh(@RequestBody Map<String, String> request) {
        String refreshToken = request.get("refreshToken");
        if (refreshToken == null || refreshToken.isEmpty()) {
            throw new AuthException("刷新令牌不能为空");
        }
        
        AuthResponse response = authService.refresh(refreshToken);
        return ResponseEntity.ok(response);
    }
    
    /**
     * 发送短信验证码
     */
    @PostMapping("/sms/send")
    public ResponseEntity<Void> sendSmsCode(@Valid @RequestBody SmsSendRequest request,
                                             HttpServletRequest httpRequest) {
        // 验证图形验证码
        if (request.getCaptchaKey() != null && request.getCaptchaCode() != null) {
            if (!captchaService.verify(request.getCaptchaKey(), request.getCaptchaCode())) {
                throw new AuthException("图形验证码错误");
            }
        }
        
        smsService.sendCode(request.getPhone(), request.getScene());
        return ResponseEntity.ok().build();
    }
    
    /**
     * 发送注册验证码（简化版）
     */
    @PostMapping("/send-code")
    public ResponseEntity<Void> sendRegisterCode(@Valid @RequestBody SmsSendRequest request,
                                                  HttpServletRequest httpRequest) {
        // 验证图形验证码
        if (request.getCaptchaKey() != null && request.getCaptchaCode() != null) {
            if (!captchaService.verify(request.getCaptchaKey(), request.getCaptchaCode())) {
                throw new AuthException("图形验证码错误");
            }
        }
        
        smsService.sendCode(request.getPhone(), "register");
        return ResponseEntity.ok().build();
    }
    
    /**
     * 短信登录
     */
    @PostMapping("/sms/login")
    public ResponseEntity<AuthResponse> smsLogin(@Valid @RequestBody SmsLoginRequest request,
                                                  HttpServletRequest httpRequest) {
        String ip = getClientIp(httpRequest);
        String userAgent = httpRequest.getHeader("User-Agent");
        
        AuthResponse response = authService.smsLogin(request, ip, userAgent);
        return ResponseEntity.ok(response);
    }
    
    /**
     * 获取微信登录二维码
     */
    @GetMapping("/wechat/qr")
    public ResponseEntity<WechatQrResponse> getWechatQr() {
        WechatQrResponse response = wechatService.getQrCode();
        return ResponseEntity.ok(response);
    }
    
    /**
     * 检查微信扫码状态
     */
    @PostMapping("/wechat/check")
    public ResponseEntity<WechatCheckResponse> checkWechatScan(@Valid @RequestBody WechatCheckRequest request) {
        WechatCheckResponse response = wechatService.checkScan(request.getQrId());
        return ResponseEntity.ok(response);
    }
    
    /**
     * 微信回调
     */
    @GetMapping("/wechat/callback")
    public ResponseEntity<String> wechatCallback(@RequestParam String code,
                                                  @RequestParam String state) {
        wechatService.handleCallback(code, state);
        // 返回一个HTML页面表示成功
        return ResponseEntity.ok()
                .contentType(MediaType.TEXT_HTML)
                .body("<html><body><h1>授权成功，请关闭页面</h1></body></html>");
    }
    
    /**
     * 获取图形验证码
     */
    @GetMapping(value = "/captcha", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CaptchaResult> getCaptcha() {
        CaptchaService.CaptchaData captchaData = captchaService.generate();
        
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(captchaData.image(), "png", baos);
            byte[] imageBytes = baos.toByteArray();
            String base64Image = Base64.getEncoder().encodeToString(imageBytes);
            
            return ResponseEntity.ok(new CaptchaResult("data:image/png;base64," + base64Image, captchaData.key()));
        } catch (Exception e) {
            log.error("生成验证码失败", e);
            throw new AuthException("生成验证码失败");
        }
    }
    
    /**
     * 发送重置密码验证码
     */
    @PostMapping("/reset/send-code")
    public ResponseEntity<Void> sendResetCode(@Valid @RequestBody SmsSendRequest request,
                                               HttpServletRequest httpRequest) {
        // 验证图形验证码
        if (request.getCaptchaKey() != null && request.getCaptchaCode() != null) {
            if (!captchaService.verify(request.getCaptchaKey(), request.getCaptchaCode())) {
                throw new AuthException("图形验证码错误");
            }
        }
        
        smsService.sendCode(request.getPhone(), "reset");
        return ResponseEntity.ok().build();
    }
    
    /**
     * 重置密码
     */
    @PostMapping("/reset/password")
    public ResponseEntity<Void> resetPassword(@Valid @RequestBody ResetPasswordRequest request) {
        // 验证密码确认
        if (!request.getNewPassword().equals(request.getConfirmPassword())) {
            throw new AuthException("两次密码输入不一致");
        }
        
        // 验证短信验证码
        if (!smsService.verifyCode(request.getPhone(), request.getCode(), "reset")) {
            throw new AuthException("短信验证码错误");
        }
        
        // 重置密码（调用userService）
        // TODO: 实现密码重置逻辑
        
        return ResponseEntity.ok().build();
    }
    
    /**
     * 发送配对码
     */
    @PostMapping("/send-pair-code")
    public ResponseEntity<Map<String, String>> sendPairCode(HttpServletRequest httpRequest) {
        Long userId = getCurrentUserId();
        // 生成6位配对码
        String pairCode = String.format("%06d", (int) (Math.random() * 1000000));
        
        // TODO: 存储配对码到Redis
        
        return ResponseEntity.ok(Map.of("pairCode", pairCode, "expiresIn", "300"));
    }
    
    /**
     * 验证配对码
     */
    @PostMapping("/verify-pair-code")
    public ResponseEntity<AuthResponse> verifyPairCode(@Valid @RequestBody PairCodeRequest request,
                                                       HttpServletRequest httpRequest) {
        String ip = getClientIp(httpRequest);
        String userAgent = httpRequest.getHeader("User-Agent");
        
        // TODO: 验证配对码并完成登录
        
        throw new AuthException("配对码验证功能开发中");
    }
    
    /**
     * 登出所有设备
     */
    @PostMapping("/logout-all-devices")
    public ResponseEntity<Void> logoutAllDevices() {
        Long userId = getCurrentUserId();
        authService.logoutAllDevices(userId);
        return ResponseEntity.ok().build();
    }
    
    /**
     * 获取当前用户设备列表
     */
    @GetMapping("/devices")
    public ResponseEntity<List<DeviceResponse>> getDevices() {
        Long userId = getCurrentUserId();
        List<DeviceResponse> devices = deviceService.getUserDevices(userId);
        return ResponseEntity.ok(devices);
    }
    
    /**
     * 租户注册
     */
    @PostMapping("/tenant-register")
    public ResponseEntity<AuthResponse> tenantRegister(@Valid @RequestBody TenantRegisterRequest request,
                                                        HttpServletRequest httpRequest) {
        String ip = getClientIp(httpRequest);
        String userAgent = httpRequest.getHeader("User-Agent");
        
        // TODO: 实现租户注册逻辑
        
        throw new AuthException("租户注册功能开发中");
    }
    
    /**
     * 获取当前认证信息
     */
    @GetMapping("/me")
    public ResponseEntity<AuthToken> getCurrentAuth(@RequestHeader("Authorization") String authHeader) {
        String token = extractToken(authHeader);
        AuthToken authToken = authService.getCurrentAuth(token);
        if (authToken == null) {
            throw new AuthException("未登录或令牌已过期");
        }
        return ResponseEntity.ok(authToken);
    }
    
    // ==================== 私有方法 ====================
    
    private Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || authentication.getPrincipal() == null) {
            throw new AuthException("未登录");
        }
        return (Long) authentication.getPrincipal();
    }
    
    private String extractToken(String authHeader) {
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        throw new AuthException("无效的Authorization头");
    }
    
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 多级代理时取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }
    
    /**
     * 验证码结果
     */
    public record CaptchaResult(String image, String key) {}
}
