package com.fuint.module.clientApi.controller;

import com.fuint.common.dto.BookDto;
import com.fuint.common.dto.BookItemDto;
import com.fuint.common.dto.UserInfo;
import com.fuint.common.enums.BookStatusEnum;
import com.fuint.common.enums.OrderModeEnum;
import com.fuint.common.enums.OrderStatusEnum;
import com.fuint.common.enums.OrderTypeEnum;
import com.fuint.common.enums.PayTypeEnum;
import com.fuint.common.enums.StatusEnum;
import com.fuint.common.enums.YesOrNoEnum;
import com.fuint.common.dto.OrderDto;
import com.fuint.repository.model.MtOrder;
import com.fuint.common.param.*;
import com.fuint.common.service.*;
import com.fuint.common.util.TokenUtil;
import com.fuint.framework.exception.BusinessCheckException;
import com.fuint.framework.pagination.PaginationResponse;
import com.fuint.framework.web.BaseController;
import com.fuint.framework.web.ResponseObject;
import com.fuint.repository.model.MtBookCate;
import com.fuint.repository.model.MtBookItem;
import com.fuint.repository.model.MtStore;
import com.fuint.repository.model.MtUser;
import java.math.BigDecimal;
import com.fuint.utils.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 预约controller
 *
 * Created by FSQ
 * CopyRight https://www.fuint.cn
 */
@Api(tags="会员端-预约相关接口")
@RestController
@AllArgsConstructor
@RequestMapping(value = "/clientApi/book")
public class ClientBookController extends BaseController {

    /**
     * 预约项目服务接口
     * */
    private BookService bookService;

    /**
     * 预约项目分类服务接口
     * */
    private BookCateService bookCateService;

    /**
     * 预约记录服务接口
     * */
    private BookItemService bookItemService;

    /**
     * 商户服务接口
     */
    private MerchantService merchantService;

    /**
     * 会员服务接口
     */
    private MemberService memberService;

    /**
     * 店铺服务接口
     * */
    private StoreService storeService;

    /**
     * 订单服务接口
     */
    private OrderService orderService;

    /**
     * 获取预约项目列表
     */
    @ApiOperation(value="获取预约项目列表", notes="获取预约项目列表")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject list(HttpServletRequest request, @RequestBody BookListParam param) throws BusinessCheckException {
        String merchantNo = request.getHeader("merchantNo") == null ? "" : request.getHeader("merchantNo");
        Integer storeId = StringUtil.isEmpty(request.getHeader("storeId")) ? 0 : Integer.parseInt(request.getHeader("storeId"));

        BookPage bookPage = new BookPage();
        bookPage.setName(param.getName());
        Integer merchantId = 0;
        if (StringUtil.isNotEmpty(merchantNo)) {
            merchantId = merchantService.getMerchantId(merchantNo);
        } else if (storeId != null && storeId > 0) {
            MtStore mtStore = storeService.queryStoreById(storeId);
            if (mtStore != null && mtStore.getMerchantId() != null) {
                merchantId = mtStore.getMerchantId();
            }
        }
        bookPage.setMerchantId(merchantId);
        bookPage.setCateId(param.getCateId());
        bookPage.setPage(param.getPage());
        bookPage.setPageSize(param.getPageSize());
        // 仅展示启用的预约项目
        bookPage.setStatus(StatusEnum.ENABLED.getKey());
        PaginationResponse<BookDto> paginationResponse = bookService.queryBookListByPagination(bookPage);

        Map<String, Object> result = new HashMap();
        result.put("content", paginationResponse.getContent());
        result.put("pageSize", paginationResponse.getPageSize());
        result.put("pageNumber", paginationResponse.getCurrentPage());
        result.put("totalRow", paginationResponse.getTotalElements());
        result.put("totalPage", paginationResponse.getTotalPages());

        return getSuccessResult(result);
    }

    /**
     * 获取预约项目详情
     */
    @ApiOperation(value="获取预约项目详情", notes="根据ID获取预约项目详情")
    @RequestMapping(value = "/detail", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject detail(@RequestBody BookDetailParam param) throws BusinessCheckException, ParseException {
        Integer bookId = param.getBookId() == null ? 0 : param.getBookId();

        BookDto bookInfo = bookService.getBookById(bookId, true);
        Map<String, Object> result = new HashMap<>();
        result.put("bookInfo", bookInfo);

        return getSuccessResult(result);
    }

    /**
     * 获取预约分类列表
     */
    @ApiOperation(value = "获取预约分类列表")
    @RequestMapping(value = "/cateList", method = RequestMethod.GET)
    @CrossOrigin
    public ResponseObject cateList(HttpServletRequest request) throws BusinessCheckException {
        Integer storeId = StringUtil.isEmpty(request.getHeader("storeId")) ? 0 : Integer.parseInt(request.getHeader("storeId"));
        Integer merchantId = merchantService.getMerchantId(request.getHeader("merchantNo"));
        List<MtBookCate> cateList = bookCateService.getAvailableBookCate(merchantId, storeId);
        Map<String, Object> result = new HashMap<>();
        result.put("cateList", cateList);
        return getSuccessResult(result);
    }

    /**
     * 是否可预约
     */
    @ApiOperation(value="获取预约项目详情", notes="根据ID获取预约项目详情")
    @RequestMapping(value = "/bookable", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject bookable(@RequestBody BookableParam param) throws BusinessCheckException,ParseException {
        List<String> result = bookService.isBookable(param);
        return getSuccessResult(result);
    }

    /**
     * 可预约时段剩余名额
     */
    @ApiOperation(value="获取可预约时段剩余名额", notes="根据ID获取可预约时段剩余名额")
    @RequestMapping(value = "/remain", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject remain(@RequestBody BookableParam param) throws BusinessCheckException,ParseException {
        List<Map<String, Object>> result = bookService.getBookableRemain(param);
        return getSuccessResult(result);
    }

    /**
     * 预约签到开始
     */
    @ApiOperation(value="预约签到开始", notes="记录预约签到开始时间")
    @RequestMapping(value = "/checkinStart", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject checkinStart(@RequestBody Map<String, Object> param) throws BusinessCheckException {
        Integer bookItemId = param.get("bookItemId") == null ? 0 : Integer.parseInt(param.get("bookItemId").toString());
        UserInfo loginInfo = TokenUtil.getUserInfo();
        if (loginInfo == null) {
            return getFailureResult(1001);
        }
        MtBookItem bookItem = bookItemService.getBookItemById(bookItemId);
        if (bookItem == null || !bookItem.getUserId().equals(loginInfo.getId())) {
            return getFailureResult(2001);
        }
        // 已签到，直接返回
        if (bookItem.getCheckinStartTime() != null) {
            Map<String, Object> result = new HashMap<>();
            result.put("checkinStartTime", bookItem.getCheckinStartTime());
            return getSuccessResult(result);
        }
        MtBookItem update = new MtBookItem();
        update.setId(bookItemId);
        update.setCheckinStartTime(new java.util.Date());
        update.setStatus(BookStatusEnum.CONFIRM.getKey());
        update.setOperator(loginInfo.getId().toString());

        bookItemService.updateBookItem(update);
        Map<String, Object> result = new HashMap<>();
        result.put("checkinStartTime", update.getCheckinStartTime());
        return getSuccessResult(result);
    }

    /**
     * 预约签到结束
     */
    @ApiOperation(value="预约签到结束", notes="记录预约签到结束时间")
    @RequestMapping(value = "/checkinEnd", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject checkinEnd(@RequestBody Map<String, Object> param) throws BusinessCheckException {
        Integer bookItemId = param.get("bookItemId") == null ? 0 : Integer.parseInt(param.get("bookItemId").toString());
        UserInfo loginInfo = TokenUtil.getUserInfo();
        if (loginInfo == null) {
            return getFailureResult(1001);
        }
        MtBookItem bookItem = bookItemService.getBookItemById(bookItemId);
        if (bookItem == null || !bookItem.getUserId().equals(loginInfo.getId())) {
            return getFailureResult(2001);
        }
        if (bookItem.getCheckinStartTime() == null) {
            return getFailureResult(2002, "未签到，无法结束");
        }
        java.util.Date endTime = new java.util.Date();
        BigDecimal hours = null;
        if (bookItem.getCheckinStartTime() != null) {
            long diffMs = endTime.getTime() - bookItem.getCheckinStartTime().getTime();
            double h = Math.max(diffMs / 3600000.0, 0);
            hours = new BigDecimal(h).setScale(1, BigDecimal.ROUND_HALF_UP);
        }
        MtBookItem update = new MtBookItem();
        update.setId(bookItemId);
        update.setCheckinEndTime(endTime);
        update.setCheckinDurationHours(hours);
        boolean isZeroDuration = hours == null || hours.compareTo(BigDecimal.ZERO) <= 0;
        update.setStatus(isZeroDuration ? BookStatusEnum.COMPLETE.getKey() : BookStatusEnum.WAIT_PAY.getKey());
        update.setOperator(loginInfo.getId().toString());
        bookItemService.updateBookItem(update);
        if (isZeroDuration && bookItem.getOrderId() != null && bookItem.getOrderId() > 0) {
            OrderDto orderDto = new OrderDto();
            orderDto.setId(bookItem.getOrderId());
            orderDto.setStatus(OrderStatusEnum.COMPLETE.getKey());
            orderService.updateOrder(orderDto);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("checkinEndTime", endTime);
        result.put("checkinDurationHours", hours);
        result.put("status", update.getStatus());
        return getSuccessResult(result);
    }

    /**
     * 预约提交
     */
    @ApiOperation(value = "预约提交")
    @RequestMapping(value = "/submit", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject submit(HttpServletRequest request, @RequestBody Map<String, Object> param) throws BusinessCheckException, ParseException {
        Integer storeId = StringUtil.isEmpty(request.getHeader("storeId")) ? 0 : Integer.parseInt(request.getHeader("storeId"));
        String bookId = param.get("bookId") == null ? "" : param.get("bookId").toString();
        String orderGoodsId = param.get("orderGoodsId") == null ? "" : param.get("orderGoodsId").toString();
        String remark = param.get("remark") == null ? "" : param.get("remark").toString();
        String mobile = param.get("mobile") == null ? "" : param.get("mobile").toString();
        String contact = param.get("contact") == null ? "" : param.get("contact").toString();
        String date = param.get("date") == null ? "" : param.get("date").toString();
        String time = param.get("time") == null ? "" : param.get("time").toString();

        UserInfo loginInfo = TokenUtil.getUserInfo();
        if (null == loginInfo) {
            return getFailureResult(1001);
        }

        MtUser mtUser = memberService.queryMemberById(loginInfo.getId());
        BookDto bookInfo = bookService.getBookById(Integer.parseInt(bookId), true);
        if (bookInfo == null) {
            return getFailureResult(2001);
        }

        if ((storeId == null || storeId <= 0) && bookInfo.getStoreId() != null && bookInfo.getStoreId() > 0) {
            storeId = bookInfo.getStoreId();
        }

        MtBookItem mtBookItem = new MtBookItem();
        mtBookItem.setCateId(bookInfo.getCateId());
        mtBookItem.setUserId(mtUser.getId());
        mtBookItem.setRemark(remark);
        mtBookItem.setMerchantId(mtUser.getMerchantId());
        mtBookItem.setStoreId(storeId);
        mtBookItem.setMobile(mobile);
        mtBookItem.setContact(contact);
        mtBookItem.setBookId(bookInfo.getId());
        mtBookItem.setServiceDate(date);
        mtBookItem.setServiceTime(time);
        if (StringUtil.isNotBlank(orderGoodsId)) {
            mtBookItem.setGoodsId(Integer.parseInt(orderGoodsId));
        }
        MtBookItem result = bookItemService.addBookItem(mtBookItem);

        return getSuccessResult(result);
    }

    /**
     * 获取我的预约
     */
    @ApiOperation(value = "获取我的预约")
    @RequestMapping(value = "/myBook", method = RequestMethod.GET)
    @CrossOrigin
    public ResponseObject myBook(HttpServletRequest request) throws BusinessCheckException {
        String status = request.getParameter("status") == null ? "" : request.getParameter("status");
        BookItemPage bookItemPage = new BookItemPage();
        Integer merchantId = merchantService.getMerchantId(request.getHeader("merchantNo"));
        if (merchantId > 0) {
            bookItemPage.setMerchantId(merchantId);
        }
        UserInfo loginInfo = TokenUtil.getUserInfo();
        bookItemPage.setUserId(loginInfo.getId());
        if (StringUtil.isNotEmpty(status)) {
            bookItemPage.setStatus(status);
        }

        PaginationResponse<BookItemDto> paginationResponse = bookItemService.queryBookItemListByPagination(bookItemPage);

        Map<String, Object> result = new HashMap<>();
        result.put("content", paginationResponse.getContent());
        result.put("pageSize", paginationResponse.getPageSize());
        result.put("pageNumber", paginationResponse.getCurrentPage());
        result.put("totalRow", paginationResponse.getTotalElements());
        result.put("totalPage", paginationResponse.getTotalPages());
        result.put("statusList", BookStatusEnum.getBookStatusList(BookStatusEnum.DELETE.getKey()));

        return getSuccessResult(result);
    }

    /**
     * 获取我的最新预约
     */
    @ApiOperation(value = "获取我的最新预约")
    @RequestMapping(value = "/myLatest", method = RequestMethod.GET)
    @CrossOrigin
    public ResponseObject myLatest(HttpServletRequest request) throws BusinessCheckException {
        BookItemPage bookItemPage = new BookItemPage();
        Integer merchantId = merchantService.getMerchantId(request.getHeader("merchantNo"));
        if (merchantId > 0) {
            bookItemPage.setMerchantId(merchantId);
        }
        UserInfo loginInfo = TokenUtil.getUserInfo();
        bookItemPage.setUserId(loginInfo.getId());
        bookItemPage.setPage(1);
        bookItemPage.setPageSize(1);

        PaginationResponse<BookItemDto> paginationResponse = bookItemService.queryBookItemListByPagination(bookItemPage);
        BookItemDto latest = null;
        if (paginationResponse.getContent() != null && paginationResponse.getContent().size() > 0) {
            latest = paginationResponse.getContent().get(0);
        }

        Map<String, Object> result = new HashMap<>();
        result.put("bookInfo", latest);
        return getSuccessResult(result);
    }

    /**
     * 预约完成
     */
    @ApiOperation(value = "预约完成")
    @RequestMapping(value = "/complete", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject complete(@RequestBody Map<String, Object> param) throws BusinessCheckException {
        Integer bookItemId = param.get("bookItemId") == null ? 0 : Integer.parseInt(param.get("bookItemId").toString());
        UserInfo loginInfo = TokenUtil.getUserInfo();
        if (loginInfo == null) {
            return getFailureResult(1001);
        }
        if (bookItemId <= 0) {
            return getFailureResult(2001);
        }
        MtBookItem bookItem = bookItemService.getBookItemById(bookItemId);
        if (bookItem == null || !bookItem.getUserId().equals(loginInfo.getId())) {
            return getFailureResult(2001);
        }
        MtBookItem update = new MtBookItem();
        update.setId(bookItemId);
        update.setStatus(BookStatusEnum.COMPLETE.getKey());
        update.setOperator(loginInfo.getId().toString());
        bookItemService.updateBookItem(update);
        if (bookItem.getOrderId() != null && bookItem.getOrderId() > 0) {
            OrderDto orderDto = new OrderDto();
            orderDto.setId(bookItem.getOrderId());
            orderDto.setStatus(OrderStatusEnum.COMPLETE.getKey());
            orderService.updateOrder(orderDto);
        }
        return getSuccessResult(update);
    }


    /**
     * 取消预约
     */
    @ApiOperation(value = "取消预约")
    @RequestMapping(value = "/cancel", method = RequestMethod.GET)
    @CrossOrigin
    public ResponseObject cancel(HttpServletRequest request) throws BusinessCheckException {
        String bookId = request.getParameter("bookId");
        String remark = request.getParameter("remark") == null ? "会员取消" : request.getParameter("remark");
        UserInfo mtUser = TokenUtil.getUserInfo();

        if (StringUtil.isEmpty(bookId)) {
            return getFailureResult(2000, "订单不能为空");
        }

        MtBookItem bookItem = bookItemService.getBookItemById(Integer.parseInt(bookId));
        if (bookItem == null || !bookItem.getUserId().equals(mtUser.getId())) {
            return getFailureResult(2000, "预约信息有误");
        }

        Boolean result = bookItemService.cancelBook(bookItem.getId(), remark);
        return getSuccessResult(result);
    }

    /**
     * 获取我的预约详情
     */
    @ApiOperation(value="获取我的预约详情", notes="根据ID获取我的预约详情")
    @RequestMapping(value = "/myBookDetail", method = RequestMethod.POST)
    @CrossOrigin
    public ResponseObject myBookDetail(@RequestBody BookDetailParam param) throws BusinessCheckException {
        Integer bookId = param.getBookId() == null ? 0 : param.getBookId();

        BookItemDto bookInfo = bookItemService.getBookDetail(bookId);
        Map<String, Object> result = new HashMap<>();
        result.put("bookInfo", bookInfo);

        return getSuccessResult(result);
    }
}
