package shop.alien.store.feign;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.cloud.openfeign.FeignClient;
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.StoreTable;
import shop.alien.entity.store.dto.CartDTO;
import shop.alien.entity.store.dto.ChangeTableDTO;
import shop.alien.entity.store.vo.*;

import java.util.List;

/**
 * 点餐服务 Feign 客户端
 * 用于 alien-store 模块调用 alien-dining 模块的接口
 *
 * @author ssk
 * @version 1.0
 * @date 2025/01/XX
 */
@FeignClient(name = "alien-dining", url = "${feign.alienDining.url:}")
public interface DiningServiceFeign {

    // ==================== 点餐相关接口 ====================

    /**
     * 查询餐桌是否处于就餐中（免登录可调用）
     *
     * @param tableId 桌号ID
     * @return R.data 为 TableDiningStatusVO（inDining、dinerCount）
     */
    @GetMapping("/store/dining/table-dining-status")
    R<TableDiningStatusVO> getTableDiningStatus(@RequestParam("tableId") Integer tableId);

    /**
     * 获取点餐页面信息
     *
     * @param authorization 请求头 Authorization，供 dining 解析当前用户
     * @param tableId       桌号ID
     * @param dinerCount    就餐人数（首客必传；餐桌已就餐中时可省略）
     * @return R.data 为 DiningPageInfoVO
     */
    @GetMapping("/store/dining/page-info")
    R<DiningPageInfoVO> getDiningPageInfo(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam("tableId") Integer tableId,
            @RequestParam(value = "dinerCount", required = false) Integer dinerCount);

    /**
     * 搜索菜品
     *
     * @param authorization 请求头 Authorization
     * @param storeId       门店ID
     * @param keyword       搜索关键词
     * @param tableId       桌号ID
     * @return R.data 为 List&lt;CuisineListVO&gt;
     */
    @GetMapping("/store/dining/search")
    R<List<CuisineListVO>> searchCuisines(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam("storeId") Integer storeId,
            @RequestParam("keyword") String keyword,
            @RequestParam("tableId") Integer tableId);

    /**
     * 根据分类获取菜品列表
     *
     * @param authorization 请求头 Authorization
     * @param storeId       门店ID
     * @param categoryId    分类ID（可为空，查询所有）
     * @param tableId       桌号ID
     * @param page          页码（默认1）
     * @param size          每页数量（默认12）
     * @return R.data 为 List&lt;CuisineListVO&gt;
     */
    @GetMapping("/store/dining/cuisines")
    R<List<CuisineListVO>> getCuisinesByCategory(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam("storeId") Integer storeId,
            @RequestParam(value = "categoryId", required = false) Integer categoryId,
            @RequestParam("tableId") Integer tableId,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "size", defaultValue = "12") Integer size);

    /**
     * 获取菜品详情
     *
     * @param authorization 请求头 Authorization
     * @param cuisineId     菜品ID
     * @param tableId       桌号ID
     * @return R.data 为 CuisineDetailVO
     */
    @GetMapping("/store/dining/cuisine/{cuisineId}")
    R<CuisineDetailVO> getCuisineDetail(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @PathVariable("cuisineId") Integer cuisineId,
            @RequestParam("tableId") Integer tableId);

    /**
     * 获取可领取的优惠券列表
     *
     * @param authorization 请求头 Authorization
     * @param storeId       门店ID
     * @return R.data 为 List&lt;AvailableCouponVO&gt;
     */
    @GetMapping("/store/dining/coupons/available")
    R<List<AvailableCouponVO>> getAvailableCoupons(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam("storeId") Integer storeId);

    // ==================== 订单相关接口 ====================

    /**
     * 获取购物车
     *
     * @param authorization 请求头 Authorization
     * @param tableId       桌号ID
     * @return R.data 为 CartDTO
     */
    @GetMapping("/store/order/cart/{tableId}")
    R<CartDTO> getCart(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @PathVariable("tableId") Integer tableId);

    /**
     * 换桌（迁移购物车、未完成订单及关联数据，支持点餐未下单场景，无需订单号）
     *
     * @param authorization 请求头 Authorization
     * @param dto            原桌号ID、目标桌号ID、换桌原因
     * @return R.data 为迁移后的购物车 CartDTO
     */
    @PostMapping("/store/order/change-table")
    R<CartDTO> changeTable(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestBody ChangeTableDTO dto);

    /**
     * 获取订单详情
     *
     * @param authorization 请求头 Authorization
     * @param orderId       订单ID
     * @return R.data 为 OrderDetailWithChangeLogVO
     */
    @GetMapping("/store/order/detail/{orderId}")
    R<OrderDetailWithChangeLogVO> getOrderDetail(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @PathVariable("orderId") Integer orderId);

    /**
     * 获取订单列表（分页）
     *
     * @param authorization 请求头 Authorization
     * @param page          页码
     * @param size          每页数量
     * @param status        订单状态（可选）
     * @return R.data 为 IPage&lt;StoreOrderPageVO&gt;
     */
    @GetMapping("/store/order/list")
    R<IPage<StoreOrderPageVO>> getOrderList(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "size", defaultValue = "10") Integer size,
            @RequestParam(value = "status", required = false) Integer status);

    /**
     * 分页查询订单列表
     * 包含订单中的菜品数量、菜品名称、菜品图片。支持按订单编号或菜品名称搜索（限15字）
     *
     * @param authorization 请求头 Authorization，供 dining 解析当前用户
     * @param current       页码（默认1）
     * @param size         每页数量（默认10）
     * @param storeId       门店ID（可选）
     * @param tableId       桌号ID（可选）
     * @param orderStatus   订单状态（可选，0:待支付, 1:已支付, 2:已取消, 3:已完成）
     * @param keyword       搜索关键词（订单编号或菜品名称，限15字）（可选）
     * @return R.data 为 Page&lt;StoreOrderPageVO&gt;（使用具体的 Page 实现类，避免 IPage 反序列化问题）
     */
    @GetMapping("/store/order/page")
    R<Page<StoreOrderPageVO>> getOrderPage(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam(value = "current", defaultValue = "1") Long current,
            @RequestParam(value = "size", defaultValue = "10") Long size,
            @RequestParam(value = "storeId", required = false) Integer storeId,
            @RequestParam(value = "tableId", required = false) Integer tableId,
            @RequestParam(value = "orderStatus", required = false) Integer orderStatus,
            @RequestParam(value = "keyword", required = false) String keyword);

    /**
     * 查询订单变更记录
     *
     * @param authorization 请求头 Authorization
     * @param orderId       订单ID
     * @return R.data 为 List&lt;OrderChangeLogBatchVO&gt;
     */
    @GetMapping("/store/order/change-log/{orderId}")
    R<List<OrderChangeLogBatchVO>> getOrderChangeLogs(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @PathVariable("orderId") Integer orderId);

    /**
     * 商家手动完成订单（不校验支付状态）
     *
     * @param authorization 请求头 Authorization
     * @param orderId       订单ID
     * @return R.data 为 Boolean（是否成功）
     */
    @PostMapping("/store/order/complete-by-merchant/{orderId}")
    R<Boolean> completeOrderByMerchant(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @PathVariable("orderId") Integer orderId);

    // ==================== 用户相关接口 ====================

    /**
     * 获取用户信息
     * 注意：返回类型使用 Object，因为 DiningUserVo 在 alien-dining 模块中
     * 调用方需要自行转换为对应的 VO 对象
     *
     * @param authorization 请求头 Authorization
     * @return R.data 为用户信息对象
     */
    @GetMapping("/dining/user/getUserInfo")
    R<Object> getUserInfo(
            @RequestHeader(value = "Authorization", required = false) String authorization);

    // ==================== 门店信息接口 ====================

    /**
     * 根据门店ID查询桌号列表
     *
     * @param storeId 门店ID
     * @return R.data 为 List&lt;StoreTable&gt;
     */
    @GetMapping("/store/info/tables")
    R<List<StoreTable>> getTablesByStoreId(
            @RequestParam("storeId") Integer storeId);

    /**
     * 根据门店ID查询菜品种类及各类别下菜品（可选按菜品名称模糊查询）
     *
     * @param storeId 门店ID
     * @param keyword 菜品名称模糊查询关键词（可选）
     * @return R.data 为 List&lt;CategoryWithCuisinesVO&gt;
     */
    @GetMapping("/store/info/categories-with-cuisines")
    R<List<CategoryWithCuisinesVO>> getCategoriesWithCuisinesByStoreId(
            @RequestParam("storeId") Integer storeId,
            @RequestParam(value = "keyword", required = false) String keyword);

    /**
     * 删除菜品种类（仅解除绑定+逻辑删分类，价目表菜品不变）
     *
     * @param categoryId 菜品种类ID
     * @return R.data 为 Boolean
     */
    @DeleteMapping("/store/info/category/{categoryId}")
    R<Boolean> deleteCategory(@PathVariable("categoryId") Integer categoryId);

    // ==================== 文件上传接口 ====================

    /**
     * 上传图片到OSS（单个文件上传，支持图片、视频或PDF）
     *
     * @param file 文件对象
     * @return R.data 为文件路径（String）
     */
    @PostMapping(value = "/dining/file/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    R<String> uploadFile(@RequestPart("file") MultipartFile file);

    @GetMapping("/payment/prePay")
    R<Object> prePay(
            @RequestHeader(value = "Authorization", required = false) String authorization,
            @RequestParam("price") String price,
            @RequestParam("subject") String subject,
            @RequestParam("payType") String payType,
            @RequestParam("payer") String payer,
            @RequestParam("orderNo") String orderNo,
            @RequestParam("storeId") Integer storeId,
            @RequestParam(value = "couponId", required = false) Integer couponId,
            @RequestParam(value = "payerId", required = false) Integer payerId,
            @RequestParam(value = "tablewareFee", required = false) String tablewareFee,
            @RequestParam(value = "discountAmount", required = false) String discountAmount,
            @RequestParam(value = "payAmount", required = false) String payAmount);

    @GetMapping("/payment/searchOrderByOutTradeNoPath")
    R<Object> searchOrderByOutTradeNoPath(
            @RequestParam("transactionId") String transactionId,
            @RequestParam("payType") String payType,
            @RequestParam("storeId") Integer storeId);

    /**
     * 支付成功后重置餐桌与购物车（与 alien-dining {@code StoreOrderService.resetTableAfterPayment} 一致），供微信回调等业务使用。
     */
    @PostMapping("/payment/internal/resetTableAfterPayment")
    R<Void> resetTableAfterPaymentInternal(
            @RequestParam("tableId") Integer tableId);
}
