package com.bizzan.bitrade.controller.code;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.bizzan.bitrade.util.MessageResult;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
@RequestMapping("/email-code")
public class EmailCodeController {

    private static final Map<String, String> PREFIX_TYPE_MAP = new LinkedHashMap<>();

    static {
        PREFIX_TYPE_MAP.put("EMAIL_REG_CODE_", "注册验证码");
        PREFIX_TYPE_MAP.put("EMAIL_LOGIN_CODE_", "登录验证码");
        PREFIX_TYPE_MAP.put("RESET_PASSWORD_CODE_", "忘记密码");
        PREFIX_TYPE_MAP.put("EMAIL_BIND_CODE_", "邮箱绑定");
        PREFIX_TYPE_MAP.put("EMAIL_CHANGE_CODE_", "邮箱更换");
        PREFIX_TYPE_MAP.put("EMAIL_UNTIE_CODE_", "邮箱解绑");
        PREFIX_TYPE_MAP.put("EMAIL_UPDATE_CODE_", "邮箱更新");
        PREFIX_TYPE_MAP.put("EMAIL_RESET_MONEY_CODE_", "资金密码重置");
        PREFIX_TYPE_MAP.put("EMAIL_WITHDRAW_MONEY_CODE_", "提现验证");
        PREFIX_TYPE_MAP.put("EMAIL_AUTH_GOOGLE_", "Google认证");
        PREFIX_TYPE_MAP.put("EMAIL_UPDATE_PASSWORD_", "密码修改");
        PREFIX_TYPE_MAP.put("EMAIL_AGENT_", "代理商验证");
        PREFIX_TYPE_MAP.put("ADD_ADDRESS_CODE_", "添加地址验证");
    }

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询所有邮箱验证码（支持邮箱模糊查询，分页）
     */
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public MessageResult list(
            @RequestParam(value = "email", required = false) String email,
            @RequestParam(value = "pageNo", defaultValue = "1") int pageNo,
            @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> result = new ArrayList<>();

        for (Map.Entry<String, String> entry : PREFIX_TYPE_MAP.entrySet()) {
            String prefix = entry.getKey();
            String codeType = entry.getValue();

            Set<String> keys = redisTemplate.keys(prefix + "*");
            if (keys == null || keys.isEmpty()) {
                continue;
            }

            for (Object keyObj : keys) {
                String key = keyObj.toString();
                String emailAddr = key.substring(prefix.length());

                // 邮箱模糊过滤
                if (StringUtils.hasText(email) && !emailAddr.toLowerCase().contains(email.toLowerCase())) {
                    continue;
                }

                Object value = redisTemplate.opsForValue().get(key);
                if (value == null) {
                    continue;
                }

                long ttlSeconds = redisTemplate.getExpire(key, TimeUnit.SECONDS);
                long expireTimestamp;
                String expireTime;
                if (ttlSeconds < 0) {
                    expireTimestamp = Long.MAX_VALUE;
                    expireTime = "永久";
                } else {
                    expireTimestamp = System.currentTimeMillis() + ttlSeconds * 1000L;
                    expireTime = sdf.format(new Date(expireTimestamp));
                }

                Map<String, Object> item = new LinkedHashMap<>();
                item.put("codeType", codeType);
                item.put("email", emailAddr);
                item.put("code", value.toString());
                item.put("expireTime", expireTime);
                item.put("_ts", expireTimestamp);
                result.add(item);
            }
        }

        // 按过期时间倒序排序
        result.sort((a, b) -> Long.compare((Long) b.get("_ts"), (Long) a.get("_ts")));
        result.forEach(m -> m.remove("_ts"));

        int total = result.size();
        int fromIndex = (pageNo - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);
        List<Map<String, Object>> pageData = fromIndex >= total ? new ArrayList<>() : result.subList(fromIndex, toIndex);

        Map<String, Object> data = new LinkedHashMap<>();
        data.put("records", pageData);
        data.put("total", total);
        data.put("pageNo", pageNo);
        data.put("pageSize", pageSize);

        MessageResult messageResult = MessageResult.success("SUCCESS");
        messageResult.setData(data);
        return messageResult;
    }
}
