package shop.alien.store.controller;

import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.StoreTrackEvent;
import shop.alien.store.service.TrackEventService;
import shop.alien.util.common.JwtUtil;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 埋点事件Controller
 *
 * @author system
 * @since 2026-01-14
 */
@Slf4j
@Api(tags = {"埋点事件管理"})
@ApiSort(20)
@CrossOrigin
@RestController
@RequestMapping("/track")
@RequiredArgsConstructor
public class TrackEventController {

    private final TrackEventService trackEventService;

    @ApiOperation("上报埋点事件")
    @ApiOperationSupport(order = 1)
    @PostMapping("/event")
    public R<String> reportEvent(@RequestBody StoreTrackEvent trackEvent, HttpServletRequest request) {
        try {
            // 设置默认值
            if (trackEvent.getEventTime() == null) {
                trackEvent.setEventTime(new Date());
            }

            // 从JWT中获取用户ID（如果未指定）
            if (trackEvent.getUserId() == null) {
                try {
                    JSONObject userInfo = JwtUtil.getCurrentUserInfo();
                    if (userInfo != null && userInfo.get("userId") != null) {
                        trackEvent.setUserId(userInfo.getInteger("userId"));
                    }
                } catch (Exception e) {
                    log.debug("无法从JWT获取用户ID", e);
                }
            }

            // 获取IP地址
            if (trackEvent.getIpAddress() == null) {
                trackEvent.setIpAddress(getClientIpAddress(request));
            }

            // 获取User-Agent
            if (trackEvent.getUserAgent() == null) {
                trackEvent.setUserAgent(request.getHeader("User-Agent"));
            }

            // 根据User-Agent解析设备类型（如果未设置）
            if (trackEvent.getDeviceType() == null && trackEvent.getUserAgent() != null) {
                trackEvent.setDeviceType(shop.alien.store.util.UserAgentParserUtil.parseDeviceType(trackEvent.getUserAgent()));
            }

            // 异步保存埋点事件（写入Redis List）
            trackEventService.saveTrackEvent(trackEvent);

            return R.success("上报成功");
        } catch (Exception e) {
            log.error("上报埋点事件失败", e);
            return R.fail("上报失败: " + e.getMessage());
        }
    }

    @ApiOperation("手动触发统计数据计算（测试用）")
    @ApiOperationSupport(order = 2)
    @PostMapping("/statistics/calculate")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "statDate", value = "统计日期（格式：yyyy-MM-dd）", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "statType", value = "统计类型（DAILY/WEEKLY/MONTHLY）", dataType = "String", paramType = "query", required = true)
    })
    public R<String> calculateStatistics(
            @RequestParam("storeId") Integer storeId,
            @RequestParam("statDate") String statDateStr,
            @RequestParam("statType") String statType) {
        try {
            // 解析日期
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
            Date statDate = sdf.parse(statDateStr);
            
            // 验证统计类型
            if (!"DAILY".equals(statType) && !"WEEKLY".equals(statType) && !"MONTHLY".equals(statType)) {
                return R.fail("统计类型必须是 DAILY、WEEKLY 或 MONTHLY");
            }
            
            // 调用统计方法
            trackEventService.calculateAndSaveStatistics(storeId, statDate, statType);
            
            return R.success("统计数据计算成功");
        } catch (java.text.ParseException e) {
            log.error("日期格式错误: {}", statDateStr, e);
            return R.fail("日期格式错误，请使用 yyyy-MM-dd 格式");
        } catch (Exception e) {
            log.error("计算统计数据失败", e);
            return R.fail("计算统计数据失败: " + e.getMessage());
        }
    }

    @ApiOperation("统计店铺浏览量")
    @ApiOperationSupport(order = 3)
    @GetMapping("/statistics/viewCount")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "Integer", paramType = "query", required = true)
    })
    public R<Long> getStoreViewCount(@RequestParam("storeId") Integer storeId) {
        try {
            if (storeId == null || storeId <= 0) {
                return R.fail("店铺ID不能为空且必须大于0");
            }
            
            Long viewCount = trackEventService.getStoreViewCount(storeId);
            log.info("查询店铺浏览量: storeId={}, viewCount={}", storeId, viewCount);
            return R.data(viewCount);
        } catch (Exception e) {
            log.error("统计店铺浏览量失败: storeId={}", storeId, e);
            return R.fail("统计店铺浏览量失败: " + e.getMessage());
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 如果是多级代理，取第一个IP
        if (ip != null && ip.contains(",")) {
            ip = ip.split(",")[0].trim();
        }
        return ip;
    }


}