package shop.alien.store.controller;

import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.StoreBookingBusinessHours;
import shop.alien.entity.store.vo.StoreReservationListVo;
import shop.alien.store.service.StoreBookingBusinessHoursService;
import shop.alien.store.service.StoreReservationService;

import java.util.Date;
import java.util.List;

/**
 * 商家端预约信息管理 前端控制器
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Api(tags = {"商家端-预约信息管理"})
@ApiSort(16)
@CrossOrigin
@RestController
@RequestMapping("/store/reservation")
@RequiredArgsConstructor
public class StoreReservationController {

    private final StoreReservationService storeReservationService;
    private final StoreBookingBusinessHoursService storeBookingBusinessHoursService;

    @ApiOperationSupport(order = 1)
    @ApiOperation("查询商家端预约信息列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "status", value = "预约状态（可选，0:待确认 1:已确认 2:已到店 3:已取消 4:未到店超时）", dataType = "Integer", paramType = "query", required = false),
            @ApiImplicitParam(name = "dateFrom", value = "预约日期起 yyyy-MM-dd", dataType = "String", paramType = "query", required = false),
            @ApiImplicitParam(name = "dateTo", value = "预约日期止 yyyy-MM-dd", dataType = "String", paramType = "query", required = false),
            @ApiImplicitParam(name = "orderStatus", value = "订单状态（可选，0:待支付 1:待使用 2:已完成 3:已过期 4:已取消 5:已关闭 6:退款中 7:已退款 8:商家预订；不传则默认查询：待使用、已完成、已退款三种状态）", dataType = "Integer", paramType = "query", required = false),
            @ApiImplicitParam(name = "reservationUserName", value = "预约用户姓名（可选，模糊查询）", dataType = "String", paramType = "query", required = false)
    })
    @GetMapping("/list")
    public R<List<StoreReservationListVo>> getReservationList(
            @RequestParam Integer storeId,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date dateFrom,
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date dateTo,
            @RequestParam(required = false) Integer orderStatus,
            @RequestParam(required = false) String reservationUserName) {
        log.info("StoreReservationController.getReservationList?storeId={}, status={}, dateFrom={}, dateTo={}, orderStatus={}, reservationUserName={}",
                storeId, status, dateFrom, dateTo, orderStatus, reservationUserName);

        if (storeId == null) {
            return R.fail("门店ID不能为空");
        }

        try {
            List<StoreReservationListVo> list = storeReservationService.getStoreReservationList(
                    storeId, status, dateFrom, dateTo, orderStatus, reservationUserName);
            return R.data(list);
        } catch (Exception e) {
            log.error("查询商家端预约信息列表失败", e);
            return R.fail("查询失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation("商家端取消预约")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reservationId", value = "预约ID", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "cancelReason", value = "取消原因（限30字）", dataType = "String", paramType = "query", required = false)
    })
    @PostMapping("/cancel")
    public R<String> cancelReservation(
            @RequestParam Integer reservationId,
            @RequestParam(required = false) String cancelReason) {
        log.info("StoreReservationController.cancelReservation?reservationId={}&cancelReason={}", reservationId, cancelReason);

        if (reservationId == null) {
            return R.fail("预约ID不能为空");
        }

        try {
            boolean result = storeReservationService.cancelReservationByStore(reservationId, cancelReason);
            if (result) {
                return R.success("取消预约成功");
            } else {
                return R.fail("取消预约失败");
            }
        } catch (Exception e) {
            log.error("商家端取消预约失败", e);
            return R.fail("取消预约失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation("商家端删除预订信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reservationId", value = "预约ID", dataType = "Integer", paramType = "query", required = true)
    })
    @PostMapping("/delete")
    public R<String> deleteReservation(@RequestParam Integer reservationId) {
        log.info("StoreReservationController.deleteReservation?reservationId={}", reservationId);

        if (reservationId == null) {
            return R.fail("预约ID不能为空");
        }

        try {
            boolean result = storeReservationService.deleteReservationByStore(reservationId);
            if (result) {
                return R.success("删除预订信息成功");
            } else {
                return R.fail("删除预订信息失败");
            }
        } catch (Exception e) {
            log.error("商家端删除预订信息失败", e);
            return R.fail("删除预订信息失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation("商家端加时")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reservationId", value = "预约ID", dataType = "Integer", paramType = "query", required = true),
            @ApiImplicitParam(name = "addTimeStart", value = "加时开始时间（yyyy-MM-dd HH:mm:ss格式，如：2026-03-11 13:00:00）", dataType = "String", paramType = "query", required = true),
            @ApiImplicitParam(name = "addTimeMinutes", value = "加时分钟数（必须大于0）", dataType = "Integer", paramType = "query", required = true)
    })
    @PostMapping("/addTime")
    public R<String> addTime(
            @RequestParam Integer reservationId,
            @RequestParam String addTimeStart,
            @RequestParam Integer addTimeMinutes) {
        log.info("StoreReservationController.addTime?reservationId={}, addTimeStart={}, addTimeMinutes={}", 
                reservationId, addTimeStart, addTimeMinutes);

        if (reservationId == null) {
            return R.fail("预约ID不能为空");
        }

        if (addTimeStart == null || addTimeStart.trim().isEmpty()) {
            return R.fail("加时开始时间不能为空");
        }

        if (addTimeMinutes == null || addTimeMinutes <= 0) {
            return R.fail("加时分钟数必须大于0");
        }

        try {
            boolean result = storeReservationService.addTimeByStore(reservationId, addTimeStart, addTimeMinutes);
            if (result) {
                return R.success("加时成功");
            } else {
                return R.fail("加时失败");
            }
        } catch (Exception e) {
            log.error("商家端加时失败", e);
            return R.fail("加时失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation("商家端核销预约订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "verificationCode", value = "核销码/券码（user_reservation_order.verification_code）", dataType = "String", paramType = "query", required = true)
    })
    @PostMapping("/verify")
    public R<String> verifyReservation(@RequestParam String verificationCode) {
        log.info("StoreReservationController.verifyReservation?verificationCode={}", verificationCode);

        if (verificationCode == null || verificationCode.trim().isEmpty()) {
            return R.fail("核销码不能为空");
        }

        try {
            boolean result = storeReservationService.verifyReservationByCode(verificationCode);
            if (result) {
                return R.success("核销成功");
            } else {
                return R.fail("核销失败");
            }
        } catch (Exception e) {
            log.error("商家端核销预约订单失败", e);
            return R.fail("核销失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation("商家端退款（预留）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reservationId", value = "预约ID", dataType = "Integer", paramType = "query", required = true)
    })
    @PostMapping("/refund")
    public R<String> refundReservation(@RequestParam Integer reservationId) {
        log.info("StoreReservationController.refundReservation?reservationId={}", reservationId);

        if (reservationId == null) {
            return R.fail("预约ID不能为空");
        }

        try {
            boolean result = storeReservationService.refundReservation(reservationId);
            if (result) {
                return R.success("退款成功");
            } else {
                return R.fail("退款失败");
            }
        } catch (Exception e) {
            log.error("商家端退款失败", e);
            return R.fail("退款失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 7)
    @ApiOperation("通过预订设置ID查询线上预订营业时间")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "settingsId", value = "预订设置ID（store_booking_settings表的id）", dataType = "Integer", paramType = "query", required = true)
    })
    @GetMapping("/getBookingBusinessHours")
    public R<List<StoreBookingBusinessHours>> getBookingBusinessHours(@RequestParam Integer settingsId) {
        log.info("StoreReservationController.getBookingBusinessHours?settingsId={}", settingsId);

        if (settingsId == null) {
            return R.fail("预订设置ID不能为空");
        }

        try {
            List<StoreBookingBusinessHours> list = storeBookingBusinessHoursService.getListBySettingsId(settingsId);
            return R.data(list);
        } catch (Exception e) {
            log.error("查询线上预订营业时间失败", e);
            return R.fail("查询失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 8)
    @ApiOperation("商家端主动退款（调用支付退款接口并发送通知和短信）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "outTradeNo", value = "商户订单号", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "refundAmount", value = "退款金额（元）", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "refundType", value = "退款类型 0:用户取消 1:商家退款 2:部分退款等 3.扫码核销成功", required = false, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "refundReason", value = "退款原因", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "payType", value = "支付类型 alipay/wechatPay", paramType = "query", dataType = "String")
    })
    @PostMapping("/refundByOrder")
    public R<String> refundByOrder(
            @RequestParam Integer storeId,
            @RequestParam String outTradeNo,
            @RequestParam String refundAmount,
            @RequestParam(required = false) Integer refundType,
            @RequestParam(required = false) String refundReason,
            @RequestParam(defaultValue = "alipay") String payType) {
        log.info("StoreReservationController.refundByOrder storeId={}, outTradeNo={}, refundAmount={}, refundType={}, refundReason={}, payType={}", 
                storeId, outTradeNo, refundAmount, refundType, refundReason, payType);

        if (storeId == null) {
            return R.fail("门店ID不能为空");
        }
        if (outTradeNo == null || outTradeNo.trim().isEmpty()) {
            return R.fail("商户订单号不能为空");
        }
        if (refundAmount == null || refundAmount.trim().isEmpty()) {
            return R.fail("退款金额不能为空");
        }

        try {
            R<String> result = storeReservationService.refundByOrder(storeId, outTradeNo, refundAmount, refundReason, refundType, payType);
            return result;
        } catch (Exception e) {
            log.error("商家端主动退款失败", e);
            return R.fail("退款失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 9)
    @ApiOperation("通过订单ID退款（根据订单自动带出门店、商户订单号、金额、支付方式，成功时发送通知和短信）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "预订订单ID（user_reservation_order.id）", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "refundReason", value = "退款原因", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "refundType", value = "退款类型 0:用户取消 1:商家退款 2:部分退款等 3.扫码核销成功", required = false, paramType = "query", dataType = "int")
    })
    @PostMapping("/refundByOrderId")
    public R<String> refundByOrderId(
            @RequestParam Integer orderId,
            @RequestParam(required = false) String refundReason,
            @RequestParam(required = false) Integer refundType) {
        log.info("StoreReservationController.refundByOrderId?orderId={}, refundReason={}, refundType={}", orderId, refundReason, refundType);
        if (orderId == null) {
            return R.fail("订单ID不能为空");
        }
        try {
            return storeReservationService.refundByOrderId(orderId, refundReason, refundType);
        } catch (Exception e) {
            log.error("通过订单ID退款失败", e);
            return R.fail("退款失败：" + e.getMessage());
        }
    }

    @ApiOperationSupport(order = 10)
    @ApiOperation("发送订金退款短信和通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reservationId", value = "预约ID", dataType = "Integer", paramType = "query", required = true)
    })
    @PostMapping("/sendDepositRefundSmsAndNotice")
    public R<String> sendDepositRefundSmsAndNotice(@RequestParam Integer reservationId) {
        log.info("StoreReservationController.sendDepositRefundSmsAndNotice?reservationId={}", reservationId);

        if (reservationId == null) {
            return R.fail("预约ID不能为空");
        }

        try {
            boolean result = storeReservationService.sendDepositRefundSmsAndNotice(reservationId);
            if (result) {
                return R.success("发送订金退款短信和通知成功");
            } else {
                return R.fail("发送订金退款短信和通知失败");
            }
        } catch (Exception e) {
            log.error("发送订金退款短信和通知失败", e);
            return R.fail("发送失败：" + e.getMessage());
        }
    }
}
