package com.jeesharp.business.modules.food.controller;

import com.jeesharp.business.modules.food.application.FoodBookingOrderApplicationService;
import com.jeesharp.business.modules.food.application.FoodBookingRefundConfirmApplicationService;
import com.jeesharp.business.modules.food.dto.FoodBookingOrderSaveDTO;
import com.jeesharp.business.modules.food.dto.FoodBookingRefundDTO;
import com.jeesharp.business.modules.food.dto.FoodBookingRefundTriggerDTO;
import com.jeesharp.business.modules.food.dto.FoodBookingVerifyDTO;
import com.jeesharp.business.modules.food.entity.FoodBookingOrder;
import com.jeesharp.business.modules.food.vo.FoodBookingOrderInfoVO;
import com.jeesharp.business.modules.food.vo.FoodBookingOrderListVO;
import com.jeesharp.business.modules.food.vo.FoodBookingOrderQueryVO;
import com.jeesharp.framework.pojo.AjaxResult;
import com.jeesharp.framework.pojo.Page;
import com.jeesharp.framework.pojo.query.PageRespVO;
import com.jeesharp.framework.web.controller.BaseController;
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.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

/**
 * 管理端美食团购预约单接口：查询、维护、到店核销与退款。
 *
 * <p>C 端见 {@link com.jeesharp.business.food.controller.FoodMobileController}；
 * 编排见 {@link com.jeesharp.business.modules.food.application.FoodBookingOrderApplicationService}（含冻券/退券）。</p>
 *
 * @author jeesharp
 * @since 2026-05-08
 */
@RestController
@RequestMapping(value = "${jeesharp.web.adminPath}/manager/business/food/booking/v1")
@Tag(name = "美食预订订单管理")
@AllArgsConstructor
public class FoodBookingOrderController extends BaseController {

    private static final String SAVE_SUCCESS_MESSAGE = "保存成功";
    private static final String DELETE_SUCCESS_MESSAGE = "删除成功";

    private final FoodBookingOrderApplicationService foodBookingOrderApplicationService;
    private final FoodBookingRefundConfirmApplicationService foodBookingRefundConfirmApplicationService;

    @Operation(summary = "获取详情")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:info')")
    @GetMapping("info")
    public AjaxResult<FoodBookingOrderInfoVO> info(@RequestParam("id") String id) {
        FoodBookingOrderInfoVO vo = foodBookingOrderApplicationService.get(id);
        return AjaxResult.okData(vo);
    }

    @Operation(summary = "获取列表（分页）")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:list')")
    @PostMapping("list")
    public AjaxResult<PageRespVO<FoodBookingOrderListVO>> list(@RequestBody FoodBookingOrderQueryVO query) {
        PageRespVO<FoodBookingOrderListVO> page = foodBookingOrderApplicationService.findPage(new Page<FoodBookingOrder>(query), query);
        return AjaxResult.okData(page);
    }

    @Operation(summary = "保存")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:save') or @ss.hasPermission('manager:business:food:booking:create') or @ss.hasPermission('manager:business:food:booking:update')")
    @PostMapping("save")
    public AjaxResult<Void> save(@RequestBody @Valid FoodBookingOrderSaveDTO dto) {
        foodBookingOrderApplicationService.save(dto);
        return AjaxResult.ok(SAVE_SUCCESS_MESSAGE);
    }

    /**
     * 管理端按核销码核销团购券：校验已支付且未核销，更新预约状态并关闭统一单。
     */
    @Operation(summary = "到店核销")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:verify')")
    @PostMapping("verify")
    public AjaxResult<Void> verify(@RequestBody @Valid FoodBookingVerifyDTO dto) {
        foodBookingOrderApplicationService.verifyConsumeByVerifyCode(dto);
        return AjaxResult.ok("核销成功");
    }

    /**
     * 管理端发起微信退款（财务统一通道）；SUCCESS 后由 {@code FoodPayRefundSuccessHandler} 自动关单退券。
     */
    @Operation(summary = "发起微信退款")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:save') or @ss.hasPermission('manager:business:food:booking:update')")
    @PostMapping("refund/trigger")
    public AjaxResult<String> triggerRefund(@RequestBody @Valid FoodBookingRefundTriggerDTO dto) {
        return AjaxResult.okData(foodBookingOrderApplicationService.triggerBookingRefund(dto));
    }

    /**
     * 管理端退款完成补偿：渠道已退款成功但业务未关单时手工同步退券（正常无需调用）。
     */
    @Operation(summary = "退款完成补偿（同步退券）")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:save') or @ss.hasPermission('manager:business:food:booking:update')")
    @PostMapping("refund")
    public AjaxResult<Void> refund(@RequestBody @Valid FoodBookingRefundDTO dto) {
        foodBookingRefundConfirmApplicationService.confirmBookingRefund(dto);
        return AjaxResult.ok("退款处理成功");
    }

    /**
     * 运维补偿：为缺失 {@code unified_order_id} 的历史美食预约单补写统一交易单影子记录。
     */
    @Operation(summary = "补偿写入统一订单（缺失 unified_order_id 的历史单）")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:save')")
    @PostMapping("backfillUnified")
    public AjaxResult<Integer> backfillUnified() {
        return AjaxResult.okData(foodBookingOrderApplicationService.backfillUnifiedTradeMissing());
    }

    @Operation(summary = "删除")
    @PreAuthorize("@ss.hasPermission('manager:business:food:booking:delete')")
    @GetMapping("delete")
    public AjaxResult<Void> delete(@RequestParam("ids") String ids) {
        foodBookingOrderApplicationService.delete(ids);
        return AjaxResult.ok(DELETE_SUCCESS_MESSAGE);
    }
}
