package com.bizzan.bitrade.controller;

import com.bizzan.bitrade.entity.ExperienceGiftCloseReason;
import com.bizzan.bitrade.entity.ExperienceGiftRecord;
import com.bizzan.bitrade.entity.ExperienceGiftRecordStatus;
import com.bizzan.bitrade.entity.ExperienceGiftWithdraw;
import com.bizzan.bitrade.entity.ExperienceGiftWithdrawApplyResult;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.bizzan.bitrade.service.ExperienceGiftProductService;
import com.bizzan.bitrade.service.ExperienceGiftRecordService;
import com.bizzan.bitrade.service.ExperienceGiftWithdrawService;
import com.bizzan.bitrade.service.LocaleMessageSourceService;
import com.bizzan.bitrade.util.MessageResult;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.bizzan.bitrade.constant.SysConstant.SESSION_MEMBER;

/**
 * 用户端体验金接口
 */
@Slf4j
@RestController
@RequestMapping("/experience-gift")
public class ExperienceGiftController {

    @Autowired
    private ExperienceGiftRecordService experienceGiftRecordService;

    @Autowired
    private ExperienceGiftWithdrawService experienceGiftWithdrawService;

    @Autowired
    private com.bizzan.bitrade.service.ExperienceGiftProductService experienceGiftProductService;

    @Autowired
    private LocaleMessageSourceService msService;

    // ----------------------------------------------------------------
    // 响应 VO
    // ----------------------------------------------------------------

    /** 列表项 VO */
    @Data
    static class RecordVO {
        private Long id;
        private String productName;
        private BigDecimal amount;
        private BigDecimal maxProfit;
        private Integer leverage;
        /** 状态码（ordinal） */
        private Integer status;
        /** 状态文字 */
        private String statusText;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date expireAt;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date createdAt;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date usedAt;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date closedAt;
        private String coinSymbol;
        private BigDecimal pnl;
    }

    /** 详情 VO（字段与列表相同，额外含平仓信息） */
    @Data
    static class RecordDetailVO extends RecordVO {
        private Integer closeReason;
        private String closeReasonText;
        private Long positionId;
        private BigDecimal openFee;
        private BigDecimal autoClosePrice;
    }

    // ----------------------------------------------------------------
    // 工具方法
    // ----------------------------------------------------------------

    private String statusText(ExperienceGiftRecordStatus s) {
        switch (s) {
            case PENDING:  return msService.getMessage("EG_STATUS_PENDING");
            case IN_USE:   return msService.getMessage("EG_STATUS_IN_USE");
            case USED:     return msService.getMessage("EG_STATUS_USED");
            case EXPIRED:  return msService.getMessage("EG_STATUS_EXPIRED");
            case INVALID:  return msService.getMessage("EG_STATUS_INVALID");
            default:       return "";
        }
    }

    private String closeReasonText(com.bizzan.bitrade.entity.ExperienceGiftCloseReason r) {
        if (r == null) {
            return "";
        }
        switch (r) {
            case USER_MANUAL:   return msService.getMessage("EG_CLOSE_USER_MANUAL");
            case EXPIRED:       return msService.getMessage("EG_CLOSE_EXPIRED");
            case BLASTED:       return msService.getMessage("EG_CLOSE_BLASTED");
            case PROFIT_LIMIT:  return msService.getMessage("EG_CLOSE_PROFIT_LIMIT");
            case ADMIN_RECYCLE: return msService.getMessage("EG_CLOSE_ADMIN_RECYCLE");
            default:            return "";
        }
    }

    private RecordVO toVO(ExperienceGiftRecord r) {
        RecordVO vo = new RecordVO();
        vo.setId(r.getId());
        vo.setProductName(r.getProductName());
        vo.setAmount(r.getAmount());
        vo.setMaxProfit(r.getMaxProfit());
        vo.setLeverage(r.getLeverage());
        vo.setStatus(r.getStatus().getCode());
        vo.setStatusText(statusText(r.getStatus()));
        vo.setExpireAt(r.getExpireAt());
        vo.setCreatedAt(r.getCreatedAt());
        vo.setUsedAt(r.getUsedAt());
        vo.setClosedAt(r.getClosedAt());
        vo.setCoinSymbol(r.getCoinSymbol());
        vo.setPnl(r.getPnl());
        return vo;
    }

    private RecordDetailVO toDetailVO(ExperienceGiftRecord r) {
        RecordDetailVO vo = new RecordDetailVO();
        vo.setId(r.getId());
        vo.setProductName(r.getProductName());
        vo.setAmount(r.getAmount());
        vo.setMaxProfit(r.getMaxProfit());
        vo.setLeverage(r.getLeverage());
        vo.setStatus(r.getStatus().getCode());
        vo.setStatusText(statusText(r.getStatus()));
        vo.setExpireAt(r.getExpireAt());
        vo.setCreatedAt(r.getCreatedAt());
        vo.setUsedAt(r.getUsedAt());
        vo.setClosedAt(r.getClosedAt());
        vo.setCoinSymbol(r.getCoinSymbol());
        vo.setPnl(r.getPnl());
        if (r.getCloseReason() != null) {
            vo.setCloseReason(r.getCloseReason().getCode());
            vo.setCloseReasonText(closeReasonText(r.getCloseReason()));
        }
        vo.setPositionId(r.getPositionId());
        vo.setOpenFee(r.getOpenFee());
        vo.setAutoClosePrice(r.getAutoClosePrice());
        return vo;
    }

    // ----------------------------------------------------------------
    // 接口
    // ----------------------------------------------------------------

    /**
     * 汇总统计（页头数据）
     * GET /experience-gift/stats
     * 返回：totalReceived（累计领取）、cumulativeProfit（累计盈利）、withdrawable（待提现）
     */
    @GetMapping("/stats")
    public MessageResult stats(@SessionAttribute(SESSION_MEMBER) AuthMember member) {
        Map<String, Object> data = experienceGiftRecordService.memberStats(member.getId());
        MessageResult result = MessageResult.success();
        result.setData(data);
        return result;
    }

    /**
     * 生效中列表（tab=active）/ 已失效列表（tab=inactive）
     * GET /experience-gift/list?tab=active
     */
    @GetMapping("/list")
    public MessageResult list(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                              @RequestParam(defaultValue = "active") String tab) {
        List<ExperienceGiftRecord> records;
        if ("inactive".equals(tab)) {
            records = experienceGiftRecordService.findInactiveByMemberId(member.getId());
        } else {
            records = experienceGiftRecordService.findActiveByMemberId(member.getId());
        }

        List<RecordVO> vos = new ArrayList<>(records.size());
        for (ExperienceGiftRecord r : records) {
            vos.add(toVO(r));
        }

        MessageResult result = MessageResult.success();
        result.setData(vos);
        return result;
    }

    /**
     * 可用体验金下拉列表（PENDING 且未过期）
     * GET /experience-gift/available?coinSymbol=BTC/USDT
     * coinSymbol 不传时返回全部可用券（向前兼容），传入时只返回产品支持该交易对的券
     */
    @GetMapping("/available")
    public MessageResult available(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                   @RequestParam(required = false) String coinSymbol) {
        List<ExperienceGiftRecord> records;
        if (coinSymbol != null && !coinSymbol.trim().isEmpty()) {
            records = experienceGiftRecordService.findAvailableByMemberIdAndCoinSymbol(member.getId(), coinSymbol.trim());
        } else {
            records = experienceGiftRecordService.findAvailableByMemberId(member.getId());
        }

        List<RecordVO> vos = new ArrayList<>(records.size());
        for (ExperienceGiftRecord r : records) {
            vos.add(toVO(r));
        }

        MessageResult result = MessageResult.success();
        result.setData(vos);
        return result;
    }

    /**
     * 单条体验金使用详情
     * GET /experience-gift/detail/{id}
     */
    @GetMapping("/detail/{id}")
    public MessageResult detail(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                @PathVariable Long id) {
        ExperienceGiftRecord record = experienceGiftRecordService
                .findByIdAndMemberId(id, member.getId())
                .orElse(null);
        if (record == null) {
            return MessageResult.error(500, msService.getMessage("EG_RECORD_NOT_EXIST"));
        }
        MessageResult result = MessageResult.success();
        result.setData(toDetailVO(record));
        return result;
    }

    /**
     * 用户申请体验金提现（全额提现，最低100 USDT）
     * POST /experience-gift/withdraw/apply
     */
    @PostMapping("/withdraw/apply")
    public MessageResult applyWithdraw(@SessionAttribute(SESSION_MEMBER) AuthMember member) {
        ExperienceGiftWithdrawApplyResult applyResult = experienceGiftWithdrawService.applyWithdraw(member.getId());
        switch (applyResult) {
            case SUCCESS:
                return MessageResult.success(msService.getMessage("EG_WITHDRAW_SUCCESS"));
            case BELOW_MIN_AMOUNT:
                return MessageResult.error(500, msService.getMessage("EG_WITHDRAW_MIN_AMOUNT"));
            default:
                return MessageResult.error(500, msService.getMessage("EG_WITHDRAW_PENDING_EXISTS"));
        }
    }

    /**
     * 用户查询自己的提现记录
     * GET /experience-gift/withdraw/list
     */
    @GetMapping("/withdraw/list")
    public MessageResult withdrawList(@SessionAttribute(SESSION_MEMBER) AuthMember member) {
        List<ExperienceGiftWithdraw> list = experienceGiftWithdrawService.listByMemberId(member.getId());
        MessageResult result = MessageResult.success();
        result.setData(list);
        return result;
    }
}
