package com.jeesharp.business.setting.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import com.jeesharp.business.modules.setting.application.FeedbackApplicationService;
import com.jeesharp.business.modules.setting.dto.FeedbackSubmitDTO;
import com.jeesharp.business.modules.setting.entity.Feedback;
import com.jeesharp.business.modules.setting.vo.FeedbackQueryVO;
import com.jeesharp.business.modules.setting.vo.FeedbackVO;
import com.jeesharp.framework.file.options.UploadOptions;
import com.jeesharp.framework.file.result.UploadResult;
import com.jeesharp.framework.file.service.FileStorageService;
import com.jeesharp.framework.memberauth.utils.MemberAuthUtils;
import com.jeesharp.framework.pojo.AjaxResult;
import com.jeesharp.framework.pojo.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Method;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 移动端意见反馈接口。
 * 兼容文档路径 /mobile/setting/feedback/* 与小程序现有路径 /mobile/feedback/*。
 */
@RestController
@RequestMapping("${jeesharp.web.mobilePath}")
@Tag(name = "移动端-意见反馈")
@AllArgsConstructor
public class FeedbackMobileController {

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

    private final FeedbackApplicationService feedbackApplicationService;
    private final FileStorageService fileStorageService;

    @Operation(summary = "反馈列表")
    @GetMapping({"/feedback/list", "/setting/feedback/myList", "/setting/feedback/myListSimple"})
    @SaCheckLogin
    public AjaxResult<?> list(
        @RequestParam(value = "page", defaultValue = "1") Long page,
        @RequestParam(value = "pageSize", defaultValue = "10") Long pageSize,
        @RequestParam(value = "status", required = false) String statusRaw
    ) {
        String memberId = MemberAuthUtils.getLoginUserId();
        FeedbackQueryVO query = new FeedbackQueryVO();
        query.setMemberId(memberId);
        query.setStatus(parseStatusParam(statusRaw));
        query.setOrderBy("create_date desc");
        Page<Feedback> pager = new Page<>(page, pageSize);
        Page<FeedbackVO> result = feedbackApplicationService.findPage(pager, query);

        Map<String, Object> data = new LinkedHashMap<>();
        data.put("total", result.getTotal());
        data.put("page", result.getPageNo());
        data.put("pageSize", result.getPageSize());
        data.put("list", result.getRecords().stream().map(this::toFeedbackRow).toList());
        return AjaxResult.okData(data);
    }

    /**
     * 解析列表筛选状态：兼容 GET 查询串中的字符串、空串及非法占位。
     */
    private static Integer parseStatusParam(String raw) {
        if (raw == null) {
            return null;
        }
        String s = raw.trim();
        if (s.isEmpty()
            || "undefined".equalsIgnoreCase(s)
            || "null".equalsIgnoreCase(s)) {
            return null;
        }
        try {
            return Integer.valueOf(s);
        } catch (NumberFormatException ex) {
            return null;
        }
    }

    @Operation(summary = "反馈详情")
    @GetMapping({"/feedback/detail/{id}", "/setting/feedback/detail"})
    @SaCheckLogin
    public AjaxResult<?> detail(
        @org.springframework.web.bind.annotation.PathVariable(value = "id", required = false) String id,
        @RequestParam(value = "id", required = false) String requestId
    ) {
        String feedbackId = id != null ? id : requestId;
        FeedbackVO vo = feedbackApplicationService.getFeedback(feedbackId);
        if (vo == null) {
            return AjaxResult.failMsg("反馈不存在");
        }
        String memberId = MemberAuthUtils.getLoginUserId();
        if (vo.getMemberId() != null && !vo.getMemberId().equals(memberId)) {
            return AjaxResult.failMsg("无权查看该反馈");
        }
        return AjaxResult.okData(toFeedbackRow(vo));
    }

    @Operation(summary = "提交反馈")
    @PostMapping({"/feedback/submit", "/setting/feedback/submit"})
    @SaCheckLogin
    public AjaxResult<?> submit(@org.springframework.web.bind.annotation.RequestBody @Valid FeedbackSubmitDTO dto) {
        String memberId = MemberAuthUtils.getLoginUserId();
        String feedbackId = feedbackApplicationService.submitFeedback(memberId, dto);
        Map<String, Object> data = new LinkedHashMap<>();
        data.put("id", feedbackId);
        return AjaxResult.ok("提交成功", data);
    }

    @Operation(summary = "上传反馈图片")
    @PostMapping("/feedback/upload")
    @SaCheckLogin
    public AjaxResult<?> upload(@RequestPart("file") MultipartFile file) {
        UploadOptions opts = UploadOptions.builder()
            .objectId(MemberAuthUtils.getLoginUserId())
            .objectType("feedback")
            .build();
        UploadResult result = fileStorageService.uploadWithResult(file, "feedback", opts);
        Map<String, Object> data = new LinkedHashMap<>();
        data.put("imageUrl", firstNonBlank(
            readString(result, "getUrl"),
            readString(result, "getFileUrl"),
            readString(result, "getPath"),
            readString(result, "getFileName")
        ));
        data.put("path", firstNonBlank(
            readString(result, "getPath"),
            readString(result, "getUrl"),
            readString(result, "getFileUrl")
        ));
        return AjaxResult.okData(data);
    }

    private Map<String, Object> toFeedbackRow(FeedbackVO vo) {
        Map<String, Object> row = new LinkedHashMap<>();
        row.put("id", vo.getId());
        row.put("type", vo.getFeedbackType());
        row.put("title", vo.getTitle());
        row.put("content", vo.getContent());
        row.put("images", vo.getImages() != null ? vo.getImages() : List.of());
        row.put("status", normalizeStatus(vo.getStatus()));
        row.put("createTime", vo.getCreateDate() != null ? TIME_FMT.format(vo.getCreateDate()) : "");
        row.put("updateTime", vo.getHandleDate() != null ? TIME_FMT.format(vo.getHandleDate()) : "");
        row.put("replyContent", vo.getHandleResult());
        row.put("replyTime", vo.getHandleDate() != null ? TIME_FMT.format(vo.getHandleDate()) : "");
        row.put("contact", vo.getContact());
        return row;
    }

    private int normalizeStatus(Integer status) {
        if (status == null) {
            return 0;
        }
        return Math.min(status, 2);
    }

    private String firstNonBlank(String... values) {
        for (String value : values) {
            if (value != null && !value.isBlank()) {
                return value;
            }
        }
        return "";
    }

    private String readString(Object target, String methodName) {
        if (target == null) {
            return "";
        }
        try {
            Method method = target.getClass().getMethod(methodName);
            Object value = method.invoke(target);
            return value != null ? String.valueOf(value) : "";
        } catch (Exception ex) {
            return "";
        }
    }
}
