package com.ycwl.basic.service.printer;

import com.ycwl.basic.model.mobile.face.FaceRecognizeResp;
import com.ycwl.basic.model.mobile.order.PriceObj;
import com.ycwl.basic.model.pc.printer.entity.PrintTaskEntity;
import com.ycwl.basic.model.pc.printer.entity.PrinterEntity;
import com.ycwl.basic.model.pc.printer.req.ReprintRequest;
import com.ycwl.basic.model.pc.printer.resp.MemberPrintResp;
import com.ycwl.basic.model.pc.printer.resp.PrinterResp;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.printer.req.FromSourceReq;
import com.ycwl.basic.model.printer.req.PrinterSyncReq;
import com.ycwl.basic.model.printer.resp.PrintTaskResp;
import com.ycwl.basic.model.printer.req.WorkerAuthReqVo;
import com.ycwl.basic.utils.ApiResponse;

import java.util.List;
import java.util.Map;

public interface PrinterService {
    List<PrinterResp> listByScenicId(Long scenicId);

    ApiResponse<List<PrinterEntity>> list(PrinterEntity condition);

    ApiResponse<PrinterEntity> get(Integer id);

    ApiResponse<Integer> add(PrinterEntity entity);

    ApiResponse<Integer> update(PrinterEntity entity);

    ApiResponse<Integer> delete(Integer id);

    List<PrintTaskResp> sync(PrinterSyncReq req);

    void taskSuccess(Integer taskId, WorkerAuthReqVo req);

    void taskFail(Integer taskId, WorkerAuthReqVo req);

    List<MemberPrintResp> getUserPhotoList(Long userId, Long scenicId, Long faceId);

    List<MemberPrintResp> getUserPhotoListByOrderId(Long orderId);

    boolean deleteUserPhoto(Long memberId, Long scenicId, Long relationId);

    Integer addUserPhoto(Long memberId, Long scenicId, String url, Long faceId, Long sourceId);

    MemberPrintResp getUserPhoto(Long memberId, Long scenicId, Long id);

    int setPhotoCropped(Long memberId, Long scenicId, Long id, String url, String crop);

    int setPhotoQuantity(Long memberId, Long scenicId, Long id, Integer quantity);

    PriceObj queryPrice(Long memberId, Long scenicId, Long faceId);

    List<Integer> addUserPhotoFromSource(Long memberId, Long scenicId, FromSourceReq req, Long faceId);

    Map<String, Object> createOrder(Long memberId, Long scenicId, Integer printerId, Long faceId);

    void batchSetUserPhotoListToPrinter(Long memberId, Long scenicId, Integer printerId);

    void setUserIsBuyItem(Long memberId, Long id, Long orderId);

    void setUserIsBuyItem(Long memberId, Long id, Long orderId, Boolean needEnhance);

    FaceRecognizeResp useSample(Long userId, Long sampleId);

    List<SourceEntity> autoAddPhotosToPreferPrint(Long faceId);

    /**
     * 查询待审核的打印任务
     * @param printerId 打印机ID(可选)
     * @return 待审核任务列表
     */
    List<PrintTaskEntity> getPendingReviewTasks(Integer printerId);

    /**
     * 更新待审核任务的URL
     * @param taskId 任务ID
     * @param url 新的打印URL
     * @return 是否成功
     */
    boolean updatePendingReviewTaskUrl(Integer taskId, String url);

    /**
     * 批准待审核任务，下发到打印队列
     * @param taskIds 任务ID列表
     * @return 成功数量
     */
    int approvePrintTasks(List<Integer> taskIds);

    /**
     * 拒绝待审核任务
     * @param taskIds 任务ID列表
     * @return 成功数量
     */
    int rejectPrintTasks(List<Integer> taskIds);

    /**
     * 从拼图记录添加到打印列表
     * @param memberId 用户ID
     * @param scenicId 景区ID
     * @param faceId 人脸ID
     * @param resultImageUrl 拼图结果图片URL
     * @param puzzleRecordId 拼图记录ID
     * @return 添加成功的MemberPrint记录ID
     */
    Integer addUserPhotoFromPuzzle(Long memberId, Long scenicId, Long faceId, String resultImageUrl, Long puzzleRecordId);

    int handleReprint(Integer id, ReprintRequest request);

    /**
     * 创建虚拟用户0元订单
     * 1. 根据source创建人脸记录（使用虚拟用户ID）
     * 2. 创建member_print记录
     * 3. 创建0元订单并触发购买后逻辑
     *
     * @param sourceId source记录ID
     * @param scenicId 景区ID
     * @param printerId 打印机ID（可选）
     * @return 订单信息
     */
    Map<String, Object> createVirtualOrder(Long sourceId, Long scenicId, Integer printerId);

    /**
     * 创建虚拟用户0元订单（支持图像增强选项）
     *
     * @param sourceId source记录ID
     * @param scenicId 景区ID
     * @param printerId 打印机ID（可选）
     * @param needEnhance 是否需要图像增强（可选）
     * @return 订单信息
     */
    Map<String, Object> createVirtualOrder(Long sourceId, Long scenicId, Integer printerId, Boolean needEnhance);

    /**
     * 创建虚拟用户0元订单（支持图像增强选项和自定义打印图片URL）
     *
     * @param sourceId source记录ID
     * @param scenicId 景区ID
     * @param printerId 打印机ID（可选）
     * @param needEnhance 是否需要图像增强（可选）
     * @param printImgUrl 打印图片URL（可选，如果提供则使用此URL进行打印）
     * @return 订单信息
     */
    Map<String, Object> createVirtualOrder(Long sourceId, Long scenicId, Integer printerId, Boolean needEnhance, String printImgUrl);

    /**
     * 创建虚拟用户订单（支持实际支付模式）
     *
     * @param sourceId source记录ID
     * @param scenicId 景区ID
     * @param printerId 打印机ID（可选）
     * @param needEnhance 是否需要图像增强（可选）
     * @param printImgUrl 打印图片URL（可选）
     * @param needActualPayment 是否需要实际支付（true: 创建待支付订单, false/null: 0元立即购买）
     * @return 订单信息
     */
    Map<String, Object> createVirtualOrder(Long sourceId, Long scenicId, Integer printerId, Boolean needEnhance, String printImgUrl, Boolean needActualPayment);

    /**
     * 批量创建虚拟用户订单（多个sourceId聚合为一笔订单、一次支付）
     *
     * @param sourceIds source记录ID列表
     * @param scenicId 景区ID
     * @param printerId 打印机ID（可选）
     * @param needEnhance 是否需要图像增强（可选）
     * @param printImgUrl 打印图片URL（可选）
     * @param needActualPayment 是否需要实际支付
     * @return 订单信息
     */
    Map<String, Object> createBatchVirtualOrder(List<Long> sourceIds, Long scenicId, Integer printerId, Boolean needEnhance, String printImgUrl, Boolean needActualPayment);

    /**
     * 根据accessKey获取打印机详情
     * @param accessKey 打印机accessKey
     * @return 打印机实体
     */
    PrinterEntity getByAccessKey(String accessKey);

    /**
     * 根据accessKey获取打印机对应的景区基础信息
     * @param accessKey 打印机accessKey
     * @return 景区基础信息
     */
    Object getScenicBasicByAccessKey(String accessKey);

    /**
     * 打开打印机（设置status=1）
     * @param accessKey 打印机accessKey
     */
    void openPrinter(String accessKey);

    /**
     * 关闭打印机（设置status=0）
     * @param accessKey 打印机accessKey
     */
    void closePrinter(String accessKey);
}