package org.springblade.modules.auth.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springblade.common.cache.CacheNames;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.Random;

/**
 * 验证码控制器
 *
 * @author Chill
 */
@RestController
@AllArgsConstructor
@RequestMapping(AppConstant.APPLICATION_AUTH_NAME + "/captcha")
@Tag(name = "验证码", description = "验证码")
public class CaptchaController {

	private final BladeRedis bladeRedis;

	/**
	 * 获取图形验证码
	 */
	@GetMapping("/oauth/captcha")
	@ApiOperationSupport(order = 1)
	@Operation(summary = "获取图形验证码", description = "返回验证码图片和key")
	public R<java.util.Map<String, String>> getCaptcha() {
		// 生成唯一key
		String key = java.util.UUID.randomUUID().toString().replace("-", "");

		// 生成4位随机验证码
		String code = generateCode(4);

		// 存储验证码到Redis，有效期5分钟
		String cacheKey = CacheNames.CAPTCHA_KEY + key;
		bladeRedis.setEx(cacheKey, code.toLowerCase(), Duration.ofMinutes(5));

		// 生成验证码图片（简单的base64图片）
		String image = generateCaptchaImage(code);

		// 返回结果
		java.util.Map<String, String> result = new java.util.HashMap<>();
		result.put("key", key);
		result.put("image", image);

		return R.data(result);
	}

	/**
	 * 发送短信验证码
	 */
	@PostMapping("/send")
	@ApiOperationSupport(order = 2)
	@Operation(summary = "发送短信验证码", description = "传入手机号")
	public R send(@Parameter(description = "手机号", required = true) @RequestParam String phone) {
		// 验证手机号格式
		if (StringUtil.isBlank(phone)) {
			return R.fail("手机号不能为空");
		}

		if (!phone.matches("^1[3-9]\\d{9}$")) {
			return R.fail("手机号格式不正确");
		}

		// 检查是否频繁发送
		String cacheKey = CacheNames.CAPTCHA_KEY + phone;
		String existCode = bladeRedis.get(cacheKey);
		if (StringUtil.isNotBlank(existCode)) {
			return R.fail("验证码已发送，请稍后再试");
		}

		// 生成6位随机验证码
		String code = generateCode(6);

		// 存储验证码到Redis，有效期5分钟
		bladeRedis.setEx(cacheKey, code, Duration.ofMinutes(5));

		// TODO: 实际项目中应该调用短信服务发送验证码
		// 这里仅做演示，直接返回验证码（生产环境应该删除）
		System.out.println("发送验证码到手机号: " + phone + ", 验证码: " + code);

		return R.success("验证码发送成功");
	}

	/**
	 * 生成随机验证码
	 *
	 * @param length 验证码长度
	 * @return 验证码
	 */
	private String generateCode(int length) {
		Random random = new Random();
		StringBuilder code = new StringBuilder();
		for (int i = 0; i < length; i++) {
			code.append(random.nextInt(10));
		}
		return code.toString();
	}

	/**
	 * 生成验证码图片（Base64格式）
	 * 使用 SVG 格式生成验证码,避免字体依赖问题
	 *
	 * @param code 验证码文本
	 * @return Base64编码的图片
	 */
	private String generateCaptchaImage(String code) {
		Random random = new Random();
		StringBuilder svg = new StringBuilder();

		svg.append("<svg xmlns='http://www.w3.org/2000/svg' width='120' height='40'>");

		// 背景
		svg.append("<rect width='120' height='40' fill='#f8f9fa'/>");

		// 绘制验证码字符
		for (int i = 0; i < code.length(); i++) {
			char c = code.charAt(i);
			int x = 15 + i * 25;
			int y = 25 + random.nextInt(5) - 2;
			int rotate = random.nextInt(30) - 15;

			// 随机颜色
			String color = String.format("#%02x%02x%02x",
				random.nextInt(100),
				random.nextInt(100),
				random.nextInt(100));

			svg.append(String.format(
				"<text x='%d' y='%d' font-size='28' font-weight='bold' fill='%s' transform='rotate(%d %d %d)'>%c</text>",
				x, y, color, rotate, x, y, c
			));
		}

		// 添加干扰线
		for (int i = 0; i < 3; i++) {
			int x1 = random.nextInt(120);
			int y1 = random.nextInt(40);
			int x2 = random.nextInt(120);
			int y2 = random.nextInt(40);
			String color = String.format("#%02x%02x%02x",
				random.nextInt(200) + 50,
				random.nextInt(200) + 50,
				random.nextInt(200) + 50);

			svg.append(String.format(
				"<line x1='%d' y1='%d' x2='%d' y2='%d' stroke='%s' stroke-width='1'/>",
				x1, y1, x2, y2, color
			));
		}

		svg.append("</svg>");

		// 转换为 Base64
		return "data:image/svg+xml;base64," + java.util.Base64.getEncoder().encodeToString(svg.toString().getBytes());
	}
}
