package com.rj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.dto.hxr.HxrLbGoodsPageData;
import com.rj.dto.hxr.HxrLbGoodsSelectResponse;
import com.rj.entity.LbGoods;
import com.rj.mapper.LbGoodsMapper;
import com.rj.service.HxrAdminBuyService;
import com.rj.service.HxrAdminGoodsService;
import com.rj.service.ILbGoodsService;
import com.rj.tenant.TenantContextHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Slf4j
@Service
@RequiredArgsConstructor
public class LbGoodsServiceImpl extends ServiceImpl<LbGoodsMapper, LbGoods> implements ILbGoodsService {

    private static final DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private final HxrAdminGoodsService hxrAdminGoodsService;

    private final HxrAdminBuyService hxrAdminBuyService;

    @Override
    public Map<String, Object> add(LbGoods entity) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (entity.getId() == null) {
                result.put("success", false);
                result.put("message", "id不能为空");
                return result;
            }
            if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "tenantId不能为空");
                return result;
            }
            entity.setTenantId(entity.getTenantId().trim());
            if (this.getById(entity.getId()) != null) {
                result.put("success", false);
                result.put("message", "该商品 id 已存在");
                return result;
            }

            applyDefaults(entity);
            LocalDateTime now = LocalDateTime.now();
            if (entity.getCreatedAt() == null) {
                entity.setCreatedAt(now);
            }
            if (entity.getUpdatedAt() == null) {
                entity.setUpdatedAt(now);
            }

            boolean ok = this.save(entity);
            result.put("success", ok);
            result.put("message", ok ? "新增成功" : "新增失败");
            if (ok) {
                result.put("data", this.getById(entity.getId()));
            }
            return result;
        } catch (Exception e) {
            log.error("货品新增异常", e);
            result.put("success", false);
            result.put("message", "新增异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> update(LbGoods entity) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (entity.getId() == null) {
                result.put("success", false);
                result.put("message", "id不能为空");
                return result;
            }
            if (this.getById(entity.getId()) == null) {
                result.put("success", false);
                result.put("message", "记录不存在");
                return result;
            }
            if (entity.getTenantId() != null) {
                entity.setTenantId(entity.getTenantId().trim());
            }

            entity.setUpdatedAt(LocalDateTime.now());
            boolean ok = this.updateById(entity);
            result.put("success", ok);
            result.put("message", ok ? "编辑成功" : "编辑失败");
            if (ok) {
                result.put("data", this.getById(entity.getId()));
            }
            return result;
        } catch (Exception e) {
            log.error("货品编辑异常", e);
            result.put("success", false);
            result.put("message", "编辑异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> deleteById(Long id) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (id == null) {
                result.put("success", false);
                result.put("message", "id不能为空");
                return result;
            }
            boolean ok = this.removeById(id);
            result.put("success", ok);
            result.put("message", ok ? "删除成功" : "删除失败");
            return result;
        } catch (Exception e) {
            log.error("货品删除异常", e);
            result.put("success", false);
            result.put("message", "删除异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    public Map<String, Object> pageQuery(
            Integer current,
            Integer size,
            String tenantId,
            Long oldId,
            Long userId,
            String title,
            Long sellerId,
            Integer isShow,
            Integer status,
            String createdAtStart,
            String createdAtEnd,
            String updatedAtStart,
            String updatedAtEnd) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (current == null || current < 1) {
                current = 1;
            }
            if (size == null || size < 1) {
                size = 10;
            }

            LambdaQueryWrapper<LbGoods> w = new LambdaQueryWrapper<>();
            if (tenantId != null && !tenantId.trim().isEmpty()) {
                w.eq(LbGoods::getTenantId, tenantId.trim());
            }
            if (oldId != null) {
                w.eq(LbGoods::getOldId, oldId);
            }
            if (userId != null) {
                w.eq(LbGoods::getUserId, userId);
            }
            if (title != null && !title.trim().isEmpty()) {
                w.like(LbGoods::getTitle, title.trim());
            }
            if (sellerId != null) {
                w.eq(LbGoods::getSellerId, sellerId);
            }
            if (isShow != null) {
                w.eq(LbGoods::getIsShow, isShow);
            }
            if (status != null) {
                w.eq(LbGoods::getStatus, status);
            }

            LocalDateTime createdStart = parseDateTime(createdAtStart);
            if (createdAtStart != null && !createdAtStart.trim().isEmpty() && createdStart == null) {
                result.put("success", false);
                result.put("message", "createdAtStart 格式错误，请使用 yyyy-MM-dd HH:mm:ss");
                return result;
            }
            LocalDateTime createdEnd = parseDateTime(createdAtEnd);
            if (createdAtEnd != null && !createdAtEnd.trim().isEmpty() && createdEnd == null) {
                result.put("success", false);
                result.put("message", "createdAtEnd 格式错误，请使用 yyyy-MM-dd HH:mm:ss");
                return result;
            }
            if (createdStart != null) {
                w.ge(LbGoods::getCreatedAt, createdStart);
            }
            if (createdEnd != null) {
                w.le(LbGoods::getCreatedAt, createdEnd);
            }

            LocalDateTime updatedStart = parseDateTime(updatedAtStart);
            if (updatedAtStart != null && !updatedAtStart.trim().isEmpty() && updatedStart == null) {
                result.put("success", false);
                result.put("message", "updatedAtStart 格式错误，请使用 yyyy-MM-dd HH:mm:ss");
                return result;
            }
            LocalDateTime updatedEnd = parseDateTime(updatedAtEnd);
            if (updatedAtEnd != null && !updatedAtEnd.trim().isEmpty() && updatedEnd == null) {
                result.put("success", false);
                result.put("message", "updatedAtEnd 格式错误，请使用 yyyy-MM-dd HH:mm:ss");
                return result;
            }
            if (updatedStart != null) {
                w.ge(LbGoods::getUpdatedAt, updatedStart);
            }
            if (updatedEnd != null) {
                w.le(LbGoods::getUpdatedAt, updatedEnd);
            }

            w.orderByDesc(LbGoods::getPrice).orderByDesc(LbGoods::getId);

            Page<LbGoods> page = this.page(new Page<>(current, size), w);
            result.put("success", true);
            result.put("message", "查询成功");
            result.put("data", page.getRecords());
            result.put("total", page.getTotal());
            result.put("current", page.getCurrent());
            result.put("size", page.getSize());
            result.put("pages", page.getPages());
            return result;
        } catch (Exception e) {
            log.error("货品分页查询异常", e);
            result.put("success", false);
            result.put("message", "查询异常：" + e.getMessage());
            return result;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> syncFromHxrGoods(String tenantId) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (tenantId == null || tenantId.trim().isEmpty()) {
                result.put("success", false);
                result.put("message", "tenantId不能为空");
                return result;
            }

            String tid = tenantId.trim();
            String previousTenantId = TenantContextHolder.getTenantId();
            TenantContextHolder.setTenantId(tid);
            try {
                HxrLbGoodsPageData firstPageData = null;
                int page = 1;
                int totalSynced = 0;
                while (true) {
                    Optional<HxrLbGoodsSelectResponse> opt = hxrAdminGoodsService.fetchGoodsPage(page);
                    if (opt.isEmpty()) {
                        if (page == 1) {
                            result.put("success", false);
                            result.put("message", "未拉取到货品（请检查 hxr.admin.goods-api-token、goods-api-app-str 或网络）");
                            result.put("synced", 0);
                            return result;
                        }
                        result.put("success", false);
                        result.put("message", "第 " + page + " 页拉取失败，已成功同步前 "
                                + (page - 1) + " 页共 " + totalSynced + " 条");
                        result.put("synced", totalSynced);
                        if (firstPageData != null) {
                            result.put("lastPage", firstPageData.lastPage());
                        }
                        result.put("pages", page - 1);
                        return result;
                    }

                    HxrLbGoodsSelectResponse body = opt.get();
                    HxrLbGoodsPageData pageData = body.data();
                    if (firstPageData == null && pageData != null) {
                        firstPageData = pageData;
                    }
                    List<LbGoods> rows = pageData != null ? pageData.list() : null;
                    if (rows == null || rows.isEmpty()) {
                        break;
                    }

                    List<LbGoods> entities = new ArrayList<>(rows.size());
                    LocalDateTime now = LocalDateTime.now();
                    for (LbGoods row : rows) {
                        if (row.getId() == null) {
                            continue;
                        }
                        row.setTenantId(tid);
                        applyDefaults(row);
                        if (row.getCreatedAt() == null) {
                            row.setCreatedAt(now);
                        }
                        if (row.getUpdatedAt() == null) {
                            row.setUpdatedAt(now);
                        }
                        entities.add(row);
                    }

                    int upserted = upsertBatch(entities);
                    if (upserted < 0) {
                        result.put("success", false);
                        result.put("message", "第 " + page + " 页保存失败，已成功同步前 "
                                + (page - 1) + " 页共 " + totalSynced + " 条");
                        result.put("synced", totalSynced);
                        if (firstPageData != null) {
                            result.put("lastPage", firstPageData.lastPage());
                        }
                        result.put("pages", page - 1);
                        return result;
                    }
                    totalSynced += upserted;

                    boolean hasMore = pageData != null && pageData.hasmore();
                    int lastPage = pageData != null ? pageData.lastPage() : page;
                    if (!hasMore || page >= lastPage) {
                        break;
                    }
                    page++;
                }

                result.put("success", true);
                result.put("message", totalSynced == 0 ? "接口成功，无货品数据" : "同步完成");
                result.put("synced", totalSynced);
                result.put("lastPage", firstPageData != null ? firstPageData.lastPage() : page);
                result.put("pages", page);
                return result;
            } finally {
                if (previousTenantId != null) {
                    TenantContextHolder.setTenantId(previousTenantId);
                } else {
                    TenantContextHolder.clear();
                }
            }
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "同步异常：" + e.getMessage());
            result.put("synced", 0);
            log.error("syncFromHxrGoods failed", e);
            return result;
        }
    }

    private int upsertBatch(List<LbGoods> entities) {
        if (entities == null || entities.isEmpty()) {
            return 0;
        }
        Map<Long, LbGoods> deduped = new LinkedHashMap<>();
        for (LbGoods entity : entities) {
            if (entity.getId() != null) {
                deduped.put(entity.getId(), entity);
            }
        }
        if (deduped.isEmpty()) {
            return 0;
        }
        List<LbGoods> rows = new ArrayList<>(deduped.values());
        try {
            baseMapper.upsertBatch(rows);
            return rows.size();
        } catch (Exception e) {
            log.error("lb_goods upsertBatch failed, size={}", rows.size(), e);
            return -1;
        }
    }

    @Override
    public Map<String, Object> rushBuy(String token, Integer maxBuyCount) {
        Map<String, Object> result = new HashMap<>();
        try {
            if (maxBuyCount == null || maxBuyCount <= 0) {
                result.put("success", false);
                result.put("message", "maxBuyCount必须大于0");
                return result;
            }

            LambdaQueryWrapper<LbGoods> w = new LambdaQueryWrapper<>();
            w.isNotNull(LbGoods::getSellerId);
            w.orderByDesc(LbGoods::getTotalMoney).orderByDesc(LbGoods::getId);
            List<LbGoods> goodsList = this.list(w);
            if (goodsList.isEmpty()) {
                result.put("success", false);
                result.put("message", "lb_goods 中无可抢购货品");
                result.put("successCount", 0);
                result.put("failCount", 0);
                result.put("details", List.of());
                return result;
            }

            List<Map<String, Object>> details = new ArrayList<>();
            int successCount = 0;
            int failCount = 0;
            boolean stoppedByMax = false;

            for (LbGoods goods : goodsList) {
                if (successCount >= maxBuyCount) {
                    stoppedByMax = true;
                    break;
                }
                if (goods.getId() == null) {
                    continue;
                }

                Map<String, Object> item = new LinkedHashMap<>();
                item.put("id", goods.getId());
                item.put("sellerId", goods.getSellerId());
                item.put("title", goods.getTitle());
                item.put("totalMoney", goods.getTotalMoney());

                HxrAdminBuyService.BuyApiResult buyResult =
                        hxrAdminBuyService.buy(goods.getId(), goods.getSellerId(), token);
                item.put("apiCode", buyResult.apiCode());
                item.put("message", buyResult.apiMsg());
                item.put("success", buyResult.success());
                details.add(item);

                if (buyResult.success()) {
                    successCount++;
                } else {
                    failCount++;
                }
            }

            result.put("success", successCount > 0);
            result.put("message", successCount > 0
                    ? "抢购完成，成功 " + successCount + " 笔，失败 " + failCount + " 笔"
                    : "抢购未成功");
            result.put("successCount", successCount);
            result.put("failCount", failCount);
            result.put("stoppedByMax", stoppedByMax);
            result.put("details", details);
            return result;
        } catch (Exception e) {
            log.error("rushBuy failed", e);
            result.put("success", false);
            result.put("message", "抢购异常：" + e.getMessage());
            return result;
        }
    }

    private static void applyDefaults(LbGoods entity) {
        if (entity.getPrice() == null) {
            entity.setPrice(BigDecimal.ZERO);
        }
        if (entity.getTotalMoney() == null) {
            entity.setTotalMoney(BigDecimal.ZERO);
        }
        if (entity.getIsShow() == null) {
            entity.setIsShow(1);
        }
        if (entity.getStatus() == null) {
            entity.setStatus(1);
        }
    }

    private static LocalDateTime parseDateTime(String text) {
        if (text == null || text.trim().isEmpty()) {
            return null;
        }
        try {
            return LocalDateTime.parse(text.trim(), DATETIME_FMT);
        } catch (DateTimeParseException e) {
            return null;
        }
    }
}
