package modules.nftt;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.StrKit;
import common.interceptor.LoginInterceptor;
import common.interceptor.empty.EmptyInterface;
import common.interceptor.role.RequiredRoleInterface;
import common.jfinal.AppConfig;
import common.model.Nftt;
import common.utils.bsn.BsnSDK;
import common.utils.http.MyController;
import common.utils.http.MyRet;
import modules.user.UserController;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class NfttController extends MyController {
    @Inject
    NfttService service;

    public void hello() {
        renderJson(MyRet.ok(service.hello()));
    }

    public void homeList() {
        renderJson(MyRet.ok("查询成功").setData(service.homeList()));
    }
    
    @EmptyInterface({"id"})
    public void findById() {
        JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
        
        String id = requestBodyJson.getString("id");
        Nftt nftt = service.findNfttById(id);

        if (nftt != null) {
            renderJson(MyRet.ok("获取成功").setData(nftt));
        } else {
            renderJson(MyRet.fail("获取失败，非法请求可能会导致ip封禁！" + id));
        }
    }
    
    @Before(LoginInterceptor.class)
    @RequiredRoleInterface({UserController.ROLE_CHECK_ADMIN, UserController.ROLE_SUPER_ADMIN})
    @EmptyInterface({"price", "name", "presale_start_time", "presale_end_time", "buying_start_time", "author", "max_quantity", "detail_image_list"})
    public void create() {
        JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);

        Nftt nftt = new Nftt(); // 创建 Model 实例

        // 获取当前用户ID作为 creator_id (需要从Session或LoginInterceptor中获取)
        // 假设你在登录成功后将用户ID存储在Session中，键名为 "user_id"
        String currentUserIdStr = getSessionAttr("user_id");
        if (StrKit.isBlank(currentUserIdStr)) {
            renderJson(MyRet.fail("创建失败: 未获取到用户信息，请重新登录"));
            return;
        }
        nftt.set("creator_id", new Integer(currentUserIdStr));

        try {
            // ** price (decimal) **
            // JSON 可能是 Double、Integer 或 String，统一转为 BigDecimal
            Integer price = requestBodyJson.getInteger("price");
            if (price == null) {
                // 虽然 EmptyInterface 确保了不为空字符串，但可能为 null
                renderJson(MyRet.fail("售价(price)不能为空或格式不正确"));
                return;
            }
            // 可以添加额外的业务校验，例如 price 必须大于 0
            if (price < 0) {
                renderJson(MyRet.fail("售价(price)不能为负数"));
                return;
            }
            nftt.set("price", price);

            // ** name (varchar) **
            String name = requestBodyJson.getString("name");
            nftt.set("name", name);

            // ** presale_start_time (bigint) **
            Long presaleStartTime = requestBodyJson.getLong("presale_start_time");
            // 业务校验：时间戳必须是正数或非负数
            if (presaleStartTime <= 0) {
                renderJson(MyRet.fail("预售开始时间(presale_start_time)必须是有效的Unix时间戳"));
                return;
            }
            nftt.set("presale_start_time", presaleStartTime);

            // ** presale_end_time (bigint) **
            Long presaleEndTime = requestBodyJson.getLong("presale_end_time");
            if (presaleEndTime <= 0) {
                renderJson(MyRet.fail("预售结束时间(presale_end_time)必须是有效的Unix时间戳"));
                return;
            }
            nftt.set("presale_end_time", presaleEndTime);

            // ** buying_start_time (bigint) **
            Long buyingStartTime = requestBodyJson.getLong("buying_start_time");
            if (buyingStartTime <= 0) {
                renderJson(MyRet.fail("开放购买时间(buying_start_time)必须是有效的Unix时间戳"));
                return;
            }
            nftt.set("buying_start_time", buyingStartTime);

            // ** author (varchar) **
            String author = requestBodyJson.getString("author");
            nftt.set("author", author);

            // ** max_quantity (int) **
            Integer maxQuantity = requestBodyJson.getInteger("max_quantity");
            if (maxQuantity == null || maxQuantity <= 0) {
                renderJson(MyRet.fail("最大份数(max_quantity)必须是大于0的整数"));
                return;
            }
            nftt.set("max_quantity", maxQuantity);

            // ** detail_image_list (json) **
            // 数据库字段是 JSON 类型，需要存储 JSON 字符串
            // 获取 JSON 数组
            JSONArray detailImageList = requestBodyJson.getJSONArray("detail_image_list");
            if (detailImageList == null || detailImageList.isEmpty()) {
                // EmptyInterface 应该已经保证了 non-null，但可能为空数组
                // 如果图片列表不能为空，这里可以返回错误
                renderJson(MyRet.fail("介绍图URL列表(detail_image_list)不能为空"));
                return;
            }
            // 转换为 JSON 字符串存储
            nftt.set("detail_image_list", detailImageList.toJSONString());
            
            // ** banner_image_list (json) **
            JSONArray bannerImageList = requestBodyJson.getJSONArray("banner_image_list");
            if (bannerImageList == null || bannerImageList.isEmpty()) {
                renderJson(MyRet.fail("banner URL列表(banner_image_list)不能为空"));
                return;
            }
            nftt.set("banner_image_list", bannerImageList.toJSONString());

            // ** purchased_quantity (int) - 默认值 **
            // 这是一个内部字段，通常在创建时初始化为 0
            nftt.set("purchased_quantity", 0);

            // ** crate_time, update_time (bigint) - 默认时间戳 **
            long currentTimeMillis = System.currentTimeMillis();
            nftt.set("create_time", currentTimeMillis);
            nftt.set("update_time", currentTimeMillis);

            // ** is_deleted (int) - 默认值 **
            nftt.set("is_deleted", 0); // 0表示未删除

            // 打印 Nftt 对象内部实际存储的属性，进行调试验证
            AppConfig.LOGGER.info("Nftt Model 的内部数据 (for debug): {}", nftt);

            if (service.save(nftt)) {
                // 在链上创建NFT
                JSONObject createResponse = BsnSDK.createNft(name, detailImageList.get(0).toString(), maxQuantity, "DLTBH_NFT_" + nftt.getId());
                nftt.setBsnStatusJson(createResponse.toJSONString());
                nftt.update();
                
                if (createResponse.getInteger("code") == 0) {
                    renderJson(MyRet.ok("NFT创建成功，等待上链，请刷新查看").setData(nftt));
                } else {
                    renderJson(MyRet.fail("NFT创建失败(Bsn)，请联系开发者").setData(createResponse));
                }
            } else {
                renderJson(MyRet.fail("创建失败，原因未知，请将此日志提供给开发者" + nftt).setData(nftt));
            }
        } catch (NumberFormatException e) {
            // 捕获可能发生的数字转换异常
            renderJson(MyRet.fail("参数格式不正确，请检查数字或时间戳字段: " + e.getMessage()));
        } catch (Exception e) {
            // 捕获其他未知异常
            renderJson(MyRet.fail("创建失败：" + e.getMessage()));
            e.printStackTrace(); // 打印堆栈跟踪，便于调试
        }
    }

    /**
     * 更新NFT模板的方法，传什么更新什么，不传就不更新，id必须传
     */
    @Before(LoginInterceptor.class)
    @RequiredRoleInterface({UserController.ROLE_CHECK_ADMIN, UserController.ROLE_SUPER_ADMIN})
    @EmptyInterface({"id"})
    public void updateByAdmin() {
        JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
        String id = requestBodyJson.getString("id");

        Nftt nftt = service.findNfttById(id);
        
        if (nftt == null) {
            renderJson(MyRet.fail("nft模板获取不合法，该id对应的nftt不存在：" + id));
            return;
        }

        // 名字
        String name = requestBodyJson.getString("name");
        if (StrKit.notBlank(name)) {
            nftt.set("name", name);
        }
        
        // 价格
        try {
            BigDecimal price = requestBodyJson.getBigDecimal("price");
            if (price != null) {
                // 可以添加额外的业务校验，例如 price 必须大于 0
                if (price.compareTo(BigDecimal.ZERO) < 0) {
                    renderJson(MyRet.fail("售价(price)不能为负数"));
                    return;
                }

                nftt.set("price", price);
            }            
        } catch (Exception e) {
            renderJson(MyRet.fail("你传入的 price 有些问题：" + e.getMessage()).setData(requestBodyJson));
            
            return;
        }

        // 预售开始时间
        try {
            Long presaleStartTime = requestBodyJson.getLong("presale_start_time");
            if (presaleStartTime != null) {
                // 业务校验：时间戳必须是正数或非负数
                if (presaleStartTime <= 0) {
                    renderJson(MyRet.fail("预售开始时间(presale_start_time)必须是有效的Unix时间戳"));
                    return;
                }
                nftt.set("presale_start_time", presaleStartTime);
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("你传入的 presale_start_time 有些问题：" + e.getMessage()).setData(requestBodyJson));

            return;
        }

        // 预售结束时间
        try {
            Long presaleEndTime = requestBodyJson.getLong("presale_end_time");
            if (presaleEndTime != null) {
                if (presaleEndTime <= 0) {
                    renderJson(MyRet.fail("预售结束时间(presale_end_time)必须是有效的Unix时间戳"));
                    return;
                }
                nftt.set("presale_end_time", presaleEndTime);
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("你传入的 presale_end_time 有些问题：" + e.getMessage()).setData(requestBodyJson));

            return;
        }

        // 开始购买时间
        try {
            Long buyingStartTime = requestBodyJson.getLong("buying_start_time");
            if (buyingStartTime != null) {
                if (buyingStartTime <= 0) {
                    renderJson(MyRet.fail("开放购买时间(buying_start_time)必须是有效的Unix时间戳"));
                    return;
                }
                nftt.set("buying_start_time", buyingStartTime);
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("你传入的 buying_start_time 有些问题：" + e.getMessage()).setData(requestBodyJson));

            return;
        }

        // 已购入份数
        try {
            Integer purchasedQuantity = requestBodyJson.getInteger("purchased_quantity");
            if (purchasedQuantity != null) {
                if (purchasedQuantity <= 0) {
                    renderJson(MyRet.fail("已购入份数(purchased_quantity)必须是大于0的整数"));
                    return;
                }
                nftt.set("purchased_quantity", purchasedQuantity);
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("你传入的 purchased_quantity 有些问题：" + e.getMessage()).setData(requestBodyJson));

            return;
        }

        // 最大份数
        try {
            Integer maxQuantity = requestBodyJson.getInteger("max_quantity");
            if (maxQuantity != null) {
                if (maxQuantity <= 0) {
                    renderJson(MyRet.fail("最大份数(max_quantity)必须是大于0的整数"));
                    return;
                }
                nftt.set("max_quantity", maxQuantity);
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("你传入的 max_quantity 有些问题：" + e.getMessage()).setData(requestBodyJson));

            return;
        }

        // 作者修改
        String author = requestBodyJson.getString("author");
        if (StrKit.notBlank(author)) {
            nftt.set("author", author);
        }
        
        // 详情列表
        JSONArray detailImageList = requestBodyJson.getJSONArray("detail_image_list");
        if (detailImageList != null) {
            nftt.set("detail_image_list", detailImageList.toJSONString());
        }

        // banner图片列表
        JSONArray bannerImageList = requestBodyJson.getJSONArray("banner_image_list");
        if (bannerImageList != null) {
            nftt.set("banner_image_list", bannerImageList.toJSONString());
        }
        
        // 最后执行更新
        if (nftt.update()) {
            renderJson(MyRet.ok("更新成功").setData(nftt));
        } else {
            renderJson(MyRet.fail("更新失败，请将此日志复制给开发者" + nftt).setData(nftt));
        }
    }

    /**
     * nftt查询
     */
    @EmptyInterface({"page_size", "page_number"})
    public void nftts() {
        JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
        
        // 页面大小
        String pageSizeStr = requestBodyJson.getString("page_size");
        int pageSizeInt;
        try {
            pageSizeInt = Integer.parseInt(pageSizeStr);

            if (pageSizeInt <= 0) {
                renderJson(MyRet.fail("页面大小(page_size)期待是正整数，你传的是: " + pageSizeStr));
                return;
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("页面大小(page_size)格式不正确: " + e.getMessage()));
            return;
        }

        // 页码
        String pageNumberStr = requestBodyJson.getString("page_number");
        int pageNumberInt;
        try {
            pageNumberInt = Integer.parseInt(pageNumberStr);

            if (pageNumberInt <= 0) {
                renderJson(MyRet.fail("页码(page_number)期待是正整数，你传的是: " + pageNumberStr));
                return;
            }
        } catch (Exception e) {
            renderJson(MyRet.fail("页码(page_number)格式不正确: " + e.getMessage()));
            return;
        }
        
        String keywords = requestBodyJson.getString("keywords");

        // 最终结果封装
        List<Nftt> nfttList = service.nfttList(pageNumberInt, pageSizeInt, keywords);
        long nfttCount = service.count(keywords);

        Map<String, Object> response = new HashMap<>();
        response.put("list", nfttList);
        response.put("total_row", nfttList.toArray().length);
        response.put("total_page", 1 + (nfttList.toArray().length / pageSizeInt));
        response.put("page_size", pageSizeInt);
        response.put("page_number", pageNumberInt);
        response.put("total_user_count", nfttCount);

        renderJson(MyRet.ok("查询成功").setData(response));
    }
}
