package shop.alien.store.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import shop.alien.entity.result.R;
import shop.alien.entity.store.WechatPartnerApplyment;
import shop.alien.store.service.WeChatPartnerApplymentService;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 微信支付服务商 — 特约商户进件
 * <p>
 * 对外路径与微信 API 路径段对齐：{@code .../v3/applyment4sub/applyment/}，
 * 实际转发至 {@code https://api.mch.weixin.qq.com/v3/applyment4sub/applyment/}。
 * </p>
 */
@Slf4j
@Api(tags = {"微信支付服务商-特约进件"})
@CrossOrigin
@RestController
@RequestMapping("/payment/wechatPartner")
@RequiredArgsConstructor
public class WeChatPartnerApplymentController {

    private final WeChatPartnerApplymentService weChatPartnerApplymentService;

    /**
     * 提交特约商户进件申请单（对应微信 {@code POST /v3/applyment4sub/applyment/}）
     * <p>
     * 请求体 JSON 字段以微信支付官方文档为准（如 business_code、contact_info、subject_info、
     * bank_account_info 等），本接口不做字段级校验，原样转发。
     * </p>
     *
     * @param requestBody    与微信文档一致的 JSON 字符串
     * @param idempotencyKey 可选，传入 {@code Idempotency-Key}，同一业务单重试时请保持不变
     * @param storeId        可选，本系统门店 {@code store_info.id}；审核通过后将微信 {@code sub_mchid} 写入该门店
     */
    @ApiOperation("特约商户进件-提交申请单（转发微信 /v3/applyment4sub/applyment/）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Idempotency-Key", value = "幂等键，可选；重试同一进件时请与首次一致", paramType = "header", dataType = "String"),
            @ApiImplicitParam(name = "storeId", value = "门店ID store_info.id，可选；用于审核通过后回写 wechat_sub_mchid", paramType = "query", dataType = "Integer")
    })
    @PostMapping(value = "/v3/applyment4sub/applyment", consumes = MediaType.APPLICATION_JSON_VALUE)
    public R<Map<String, Object>> submitApplyment(
            @RequestBody String requestBody,
            @RequestHeader(value = "Idempotency-Key", required = false) String idempotencyKey,
            @RequestParam(value = "storeId", required = false) Integer storeId) {
        log.info("WeChatPartnerApplymentController.submitApplyment bodyLen={}, idempotencyKeyPresent={}, storeId={}",
                requestBody != null ? requestBody.length() : 0, idempotencyKey != null && !idempotencyKey.isEmpty(), storeId);
        return weChatPartnerApplymentService.submitApplyment(requestBody, idempotencyKey, storeId);
    }

    /**
     * 商户图片上传，对应微信 {@code POST /v3/merchant/media/upload}，成功返回 {@code media_id}。
     */
    @ApiOperation("特约商户进件-图片上传（转发微信 /v3/merchant/media/upload，返回 media_id）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "图片文件 JPG/PNG/BMP，≤5MB", required = true, dataType = "file", paramType = "form")
    })
    @PostMapping(value = "/v3/merchant/media/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Map<String, Object>> uploadMerchantMedia(@RequestParam("file") MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return R.fail("请选择图片文件");
        }
        try {
            return weChatPartnerApplymentService.uploadMerchantMedia(file.getBytes(), file.getOriginalFilename());
        } catch (IOException e) {
            return R.fail("读取上传文件失败: " + e.getMessage());
        }
    }

    /**
     * 申请单号查询申请状态，对应微信
     * {@code GET /v3/applyment4sub/applyment/applyment_id/{applyment_id}}
     * （<a href="https://pay.weixin.qq.com/doc/v3/partner/4012697052">文档</a>）。
     *
     * @param applymentId 微信支付分配的申请单号
     */
    @ApiOperation("特约商户进件-申请单号查询申请状态（转发微信 GET .../applyment_id/{applyment_id}）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "applyment_id", value = "微信支付申请单号", required = true, paramType = "path", dataType = "Long")
    })
    @GetMapping("/v3/applyment4sub/applyment/applyment_id/{applyment_id}")
    public R<Map<String, Object>> queryApplymentStateByApplymentId(
            @PathVariable("applyment_id") Long applymentId) {
        if (applymentId == null) {
            return R.fail("applyment_id 不能为空");
        }
        log.info("WeChatPartnerApplymentController.queryApplymentStateByApplymentId applyment_id={}", applymentId);
        return weChatPartnerApplymentService.queryApplymentStateByApplymentId(applymentId);
    }

    /**
     * 按门店查询特约商户进件状态：读本地 {@code wechat_partner_applyment} 该店最新一条记录（不调微信）。
     *
     * @param storeId 门店主键 {@code store_info.id}（进件提交时需已传同一 storeId）
     */
    @ApiOperation("特约商户进件-按门店查询进件状态（读本地库）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID store_info.id", required = true, paramType = "path", dataType = "int")
    })
    @GetMapping("/applyment/store/{storeId}")
    public R<List<WechatPartnerApplyment>> queryApplymentStateByStoreId(@PathVariable("storeId") Integer storeId) {
        log.info("WeChatPartnerApplymentController.queryApplymentStateByStoreId storeId={}", storeId);
        return weChatPartnerApplymentService.queryApplymentStateByStoreId(storeId);
    }
}
