package com.softwarebr.nunu.web.admin;

import com.brframework.common.utils.ConvertObjectUtil;
import com.brframework.common.utils.DateTimeUtils;
import com.brframework.commoncms.annatotion.AdminMenu;
import com.brframework.commoncms.annatotion.layout.EditAlertLayout;
import com.brframework.commoncms.annatotion.layout.EditLayout;
import com.brframework.commoncms.annatotion.layout.PageLayout;
import com.brframework.commoncms.annatotion.option.CmsOption;
import com.brframework.commoncms.core.Icons;
import com.brframework.commondb.core.ControllerPageHandle;
import com.brframework.commonsecurity.core.SecuritySubject;
import com.brframework.commonsecurity.core.SecurityUserDetails;
import com.brframework.commonsecurity.core.SecurityUserDetailsService;
import com.brframework.commonweb.json.JSONResult;
import com.brframework.commonweb.json.Page;
import com.brframework.commonweb.json.PageParam;
import com.brframework.commonwebadmin.aop.annotation.AOLog;
import com.google.common.collect.Lists;
import com.softwarebr.nunu.domain.VerifyPageTotal;
import com.softwarebr.nunu.dto.train.ActivityParamDTO;
import com.softwarebr.nunu.entity.train.Activity;
import com.softwarebr.nunu.entity.user.Order;
import com.softwarebr.nunu.entity.user.RefundInfo;
import com.softwarebr.nunu.globals.SystemConst;
import com.softwarebr.nunu.json.admin.train.*;
import com.softwarebr.nunu.json.admin.user.*;
import com.softwarebr.nunu.service.oper.AreaService;
import com.softwarebr.nunu.service.train.ActivityLogService;
import com.softwarebr.nunu.service.train.ActivityService;
import com.softwarebr.nunu.service.user.MemberService;
import com.softwarebr.nunu.service.user.OrderService;
import com.softwarebr.nunu.service.user.RefundInfoService;
import com.softwarebr.nunu.util.AmountConversionUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.time.LocalDateTime;

import static com.brframework.commondb.core.ControllerPageHandle.convertTo;
import static com.brframework.commondb.core.ControllerPageHandle.jpaPageConvertToPage;

/**
 * @author lilin
 * @date 2020-02-26 11:02:46
 */

@RestController
@Api(tags = "创新培训活动管理")
@AdminMenu(menuName = "创新培训活动管理", icon = Icons.TABLE)
@RequestMapping("/admin/access")
public class AdminTrainController {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private AreaService areaService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private RefundInfoService refundInfoService;

    @Autowired
    private ActivityLogService activityLogService;

    @Autowired
    @Qualifier("apiUserDetailsService")
    SecurityUserDetailsService userDetailsService;

    @ApiOperation(value = "创新培训活动列表", notes = "创新培训活动列表", produces = "text/plain")
    @GetMapping("/v1/activity/page")
    @AdminMenu(menuName = "创新培训活动管理", order = 1, url = "school")
    @PreAuthorize("hasRole('train-activity-query')")
    @PageLayout(
            options = {
                    @CmsOption(name = "添加", uriMappingMethod = "activityCreateV1")
            },
            columnOptions = {
                    @CmsOption(name = "上架", uriMappingMethod = "activityUpperV1"),
                    @CmsOption(name = "下架", uriMappingMethod = "activityLowerV1"),
                    @CmsOption(name = "审核", uriMappingMethod = "activityVerifyV1"),
                    @CmsOption(name = "活动总结", uriMappingMethod = "activitySummaryV1"),
                    @CmsOption(name = "修改", uriMappingMethod = "activityEditV1"),
                    @CmsOption(name = "首页推荐", uriMappingMethod = "activityIndexYesV1"),
                    @CmsOption(name = "取消推荐", uriMappingMethod = "activityIndexNoV1"),
                    @CmsOption(name = "活动报名下载", uriMappingMethod = "excelDownloadV1")
            }
    )
    public JSONResult<Page<ActivityResult>> activityListV1(PageParam pageParam, ActivityQueryParam param) {
        if (null != param.getAccount()) {
            param.setPublisher(memberService.findMemberIdByPhone(param.getAccount()));
        }
        Page<ActivityResult> page = jpaPageConvertToPage(activityService.pageV1(pageParam, param), pageParam, ActivityResult.class);
        for (ActivityResult activityResult : page.getList()) {
            activityResult.setAddress(areaService.addressSplicing(activityResult.getProvinceId(), activityResult.getCityId(), activityResult.getAreaId()));
            if (activityResult.getPublisher() > 0) {
                activityResult.setAccount(memberService.accessObject(activityResult.getPublisher()).getPhone());
            } else {
                activityResult.setAccount("平台");
            }
            activityResult.setTypeTitle(activityService.activityType(activityResult.getCategory()).get(activityResult.getType()));
            activityResult.setActivityStatus(activityService.activityStatusAdmin(ControllerPageHandle.convertTo(activityResult, Activity.class)));
            activityResult.setCategoryTitle(activityResult.getCategory().equals(Activity.CATEGORY_INNOVATE) ? "创新活动" : "培训活动");
            activityResult.setAddress(areaService.addressSplicing(activityResult.getProvinceId(), activityResult.getCityId(), activityResult.getAreaId()));
            activityResult.setEnrolmentCapacity(String.format("%s/%s", activityResult.getEnrolment(), activityResult.getCapacity()));
            activityResult.setStartEndDate(String.format("%s - %s", activityResult.getStartDate().format(
                    DateTimeUtils.FORMATTER_DEFAULT_YMDHMS), activityResult.getEndDate().format(DateTimeUtils.FORMATTER_DEFAULT_YMDHMS)));
            activityResult.setSignStartEndDate(String.format("%s - %s", activityResult.getSignStartDate().format(
                    DateTimeUtils.FORMATTER_DEFAULT_YMDHMS), activityResult.getSignEndDate().format(DateTimeUtils.FORMATTER_DEFAULT_YMDHMS)));
            activityResult.setVerifyTitle(SystemConst.verifyHandle(activityResult.getVerify()));
            activityResult.setUpperTitle(SystemConst.statusUpperHandle(activityResult.getStatus()));
        }
        return JSONResult.ok(page);
    }

    @ApiOperation(value = "创新培训活动状态数据统计", notes = "创新培训活动状态数据统计", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-query')")
    @GetMapping("/v1/activity/count")
    public JSONResult<VerifyPageTotal> getActivityCount(ActivityQueryParam param) {
        VerifyPageTotal verifyPageResult = new VerifyPageTotal();
        if (null != param.getAccount()) {
            param.setPublisher(memberService.findMemberIdByPhone(param.getAccount()));
        }
        verifyPageResult.setTotalCount(activityService.countV1(param));
        param.setStatus(SystemConst.STATUS_LOWER_SHELF);
        verifyPageResult.setLowerCount(activityService.countV1(param));
        param.setStatus(SystemConst.STATUS_UPPER_SHELF);
        verifyPageResult.setUpperCount(activityService.countV1(param));
        param.setStatus(null);
        param.setVerify(SystemConst.VERIFY_AWAIT);
        verifyPageResult.setVerifyAwaitCount(activityService.countV1(param));
        param.setVerify(SystemConst.VERIFY_ADOPT);
        verifyPageResult.setVerifyAdoptCount(activityService.countV1(param));
        param.setVerify(SystemConst.VERIFY_REJECT);
        verifyPageResult.setVerifyRejectCount(activityService.countV1(param));
        return JSONResult.ok(verifyPageResult);
    }

    @AOLog
    @ApiOperation(value = "下载活动报名信息")
    @GetMapping("v1/train/excel/download/{token}/{activityId}")
    public JSONResult excelDownloadV1(@ApiParam("token") @PathVariable String token, @ApiParam("活动ID") @PathVariable Long activityId, HttpServletResponse response) {
        SecurityUserDetails user = (SecurityUserDetails) userDetailsService.loadUserByUsername(token);
        SecuritySubject subject = user.getSubject();
        if(subject != null){
            activityLogService.activityExcelDownload(response, activityId);
        }
        return JSONResult.ok();
    }


    @ApiOperation(value = "修改创新培训活动信息", notes = "修改创新培训活动信息", produces = "text/plain")
    @PostMapping("/v1/activity/{id}")
    @PreAuthorize("hasRole('train-activity-edit-v1')")
    @AOLog
    @EditAlertLayout(
            paddingMappingMethod = "getActivity"
    )
    public JSONResult activityEditV1(@PathVariable Long id, @Valid @RequestBody ActivityParam param) {
        activityService.updateActivity(id, convertTo(param, ActivityParamDTO.class));
        return JSONResult.ok();
    }

    @ApiOperation(value = "添加创新培训活动信息", notes = "添加创新培训活动信息", produces = "text/plain")
    @PutMapping("/v1/activity/add")
    @PreAuthorize("hasRole('train-activity-create-v1')")
    @AOLog
    @EditLayout
    public JSONResult activityCreateV1(@Valid @RequestBody ActivityParam param) {
        activityService.saveActivity(-1L, convertTo(param, ActivityParamDTO.class));
        return JSONResult.ok();
    }

    @ApiOperation(value = "查看创新培训活动信息", notes = "查看创新培训活动信息", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-query')")
    @GetMapping("/v1/activity/{id}")
    public JSONResult<ActivityDetailsResult> getActivity(@PathVariable Long id) {
        Activity activity = activityService.accessObject(id);
        ActivityDetailsResult detailsResult = convertTo(activity, ActivityDetailsResult.class);
        detailsResult.setTypeTitle(activityService.activityType(detailsResult.getCategory()).get(detailsResult.getType()));
        detailsResult.setArea(areaService.accessObject(detailsResult.getAreaId()).getCityName());
        detailsResult.setCity(areaService.accessObject(detailsResult.getCityId()).getCityName());
        detailsResult.setProvince(areaService.accessObject(detailsResult.getProvinceId()).getCityName());
        detailsResult.setPrice(AmountConversionUtil.out(activity.getPrice()));
        return JSONResult.ok(detailsResult);
    }

    @ApiOperation(value = "创新培训活动上架", notes = "创新培训活动上架", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-upper-edit-v1')")
    @PostMapping("/v1/activity/upper/{id}")
    @AOLog
    public JSONResult activityUpperV1(@PathVariable Long id) {
        activityService.activityUpperShelf(id);
        return JSONResult.ok();
    }

    @ApiOperation(value = "创新培训活动下架", notes = "创新培训活动下架", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-lower-edit-v1')")
    @PostMapping("/v1/activity/lower/{id}")
    @AOLog
    public JSONResult activityLowerV1(@PathVariable Long id) {
        activityService.activityLowerShelf(id);
        return JSONResult.ok();
    }

    @ApiOperation(value = "创新培训活动审核", notes = "创新培训活动审核", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-verify-edit-v1')")
    @PostMapping("/v1/activity/verify/{id}")
    @EditAlertLayout
    @AOLog
    public JSONResult activityVerifyV1(@PathVariable Long id, @Valid @RequestBody ActivityVerifyParam param) {
        activityService.activityVerify(id, param.getVerify(), param.getVerifyRemark());
        return JSONResult.ok();
    }

    @ApiOperation(value = "创新培训活动首页推荐", notes = "创新培训活动首页推荐", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-index-edit-v1')")
    @PostMapping("/v1/activity/index/yes/{id}")
    @AOLog
    public JSONResult activityIndexYesV1(@PathVariable Long id) {
        activityService.activityIndexYes(id);
        return JSONResult.ok();
    }

    @ApiOperation(value = "创新培训活动取消推荐", notes = "创新培训活动取消推荐", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-index-edit-v1')")
    @PostMapping("/v1/activity/index/no/{id}")
    @AOLog
    public JSONResult activityIndexNoV1(@PathVariable Long id) {
        activityService.activityIndexNo(id);
        return JSONResult.ok();
    }

    @ApiOperation(value = "创新培训活动总结", notes = "创新培训活动总结", produces = "text/plain")
    @PreAuthorize("hasRole('train-activity-summary-edit-v1')")
    @PostMapping("/v1/activity/summary/{id}")
    @EditAlertLayout
    @AOLog
    public JSONResult activitySummaryV1(@PathVariable Long id, @Valid @RequestBody ActivitySummaryParam param) {
        Activity activity = activityService.accessObject(id);
        activity.setSummaryStatus(Activity.SUMMARY_STATUS_YES);
        activity.setSummary(param.getSummary());
        activityService.save(activity);
        return JSONResult.ok();
    }


    @ApiOperation(value = "订单信息列表", notes = "订单信息列表", produces = "text/plain")
    @GetMapping("/v1/order/page")
    @AdminMenu(menuName = "订单管理", order = 2, url = "Orders")
    @PreAuthorize("hasRole('user-order-query')")
    @PageLayout(
            columnOptions = {
                    @CmsOption(name = "查看详情", uriMappingMethod = "getOrder")
            }
    )
    public JSONResult<Page<OrderResult>> orderListV1(PageParam pageParam, OrderQueryParam param) {
        if (null != param.getAccount()) {
            param.setMemberId(memberService.findMemberIdByPhone(param.getAccount()));
        }
        if (null != param.getActivityName()) {
            param.setActivityId(activityService.getActivityByName(param.getActivityName()));
        }
        Page<OrderResult> page = jpaPageConvertToPage(orderService.page(pageParam, param), pageParam, OrderResult.class);
        for (OrderResult orderResult : page.getList()) {
            Activity activity = activityService.accessObject(orderResult.getActivityId());
            orderResult.setActivityName(activity.getName());
            orderResult.setActivityType(activityService.activityType(Activity.CATEGORY_TRAIN).get(activity.getType()));
            orderResult.setCoverUri(activity.getCoverUri());
            orderResult.setAccount(memberService.accessObject(orderResult.getMemberId()).getPhone());
            orderResult.setTotalPrice(AmountConversionUtil.out(orderResult.getTotalPrice()));
        }
        return JSONResult.ok(page);
    }

    @ApiOperation(value = "查看订单信息", notes = "查看订单信息", produces = "text/plain")
    @PreAuthorize("hasRole('user-order-query')")
    @GetMapping("/v1/order/{id}")
    public JSONResult<OrderDetailsResult> getOrder(@ApiParam("订单Id") @PathVariable Long id) {
        Order order = orderService.accessObject(id);
        OrderDetailsResult detailsResult = convertTo(order, OrderDetailsResult.class);
        Activity activity = activityService.accessObject(order.getActivityId());
        detailsResult.setAddress(areaService.addressSplicing(activity.getProvinceId(), activity.getCityId(), activity.getAreaId()));
        detailsResult.setActivityName(activity.getName());
        detailsResult.setActivityType(activityService.activityType(Activity.CATEGORY_TRAIN).get(activity.getType()));
        detailsResult.setCoverUri(activity.getCoverUri());
        detailsResult.setStartDate(activity.getStartDate());
        detailsResult.setEndDate(activity.getEndDate());
        detailsResult.setTotalPrice(AmountConversionUtil.out(detailsResult.getTotalPrice()));
        detailsResult.setPrice(AmountConversionUtil.out(detailsResult.getPrice()));
        detailsResult.setCapacity(activity.getCapacity());
        detailsResult.setAccount(memberService.accessObject(detailsResult.getMemberId()).getPhone());
        detailsResult.setDescription(activity.getDescription());
        if (order.getOrderStatus().equals(Order.ORDER_STATUS_REFUNDING)
                || order.getOrderStatus().equals(Order.ORDER_STATUS_REFUNDED)
                || order.getOrderStatus().equals(Order.ORDER_STATUS_REJECTED)) {
            RefundInfo refundinfo = refundInfoService.getRefundInfoByOrderId(order.getId());
            detailsResult.setReason(refundinfo.getReason());
            detailsResult.setVoucherPictures(null != refundinfo.getVoucherPicture()?Lists.newArrayList(refundinfo.getVoucherPicture().split(",")):Lists.newArrayList());
        }
        return JSONResult.ok(detailsResult);
    }

    @ApiOperation(value = "退款订单列表", notes = "退款订单列表", produces = "text/plain")
    @GetMapping("/v1/refund/info/page")
    @AdminMenu(menuName = "退款订单管理", order = 3, url = "rebate")
    @PreAuthorize("hasRole('user-refund-info-query')")
    @PageLayout(
            columnOptions = {
                    @CmsOption(name = "查看详情", uriMappingMethod = "getOrder"),
                    @CmsOption(name = "审核", uriMappingMethod = "refundInfoVerifyV1")
            }
    )
    public JSONResult<Page<RefundInfoResult>> refundInfoListV1(PageParam pageParam, RefundInfoQueryParam param) {
        if (null != param.getAccount()) {
            param.setMemberId(memberService.findMemberIdByPhone(param.getAccount()));
        }
        if (null != param.getActivityName()) {
            param.setActivityId(activityService.getActivityByName(param.getActivityName()));
        }
        Page<RefundInfoResult> page = jpaPageConvertToPage(refundInfoService.page(pageParam, param), pageParam, RefundInfoResult.class);
        for (RefundInfoResult refundInfoResult : page.getList()) {
            Order order = orderService.accessObject(refundInfoResult.getOrderId());
            Activity activity = activityService.accessObject(refundInfoResult.getActivityId());
            refundInfoResult.setActivityName(activity.getName());
            refundInfoResult.setActivityType(activityService.activityType(Activity.CATEGORY_TRAIN).get(activity.getType()));
            refundInfoResult.setCoverUri(activity.getCoverUri());
            refundInfoResult.setAccount(memberService.accessObject(refundInfoResult.getMemberId()).getPhone());
            refundInfoResult.setTotalPrice(AmountConversionUtil.out(order.getTotalPrice()));
            refundInfoResult.setRefundPrice(AmountConversionUtil.out(order.getTotalPrice()));
            refundInfoResult.setOrderAmount(order.getOrderAmount());
            refundInfoResult.setOrderDate(order.getCreateDate());
            refundInfoResult.setOrderNo(order.getOrderNo());
        }
        return JSONResult.ok(page);
    }

    @ApiOperation(value = "退款订单状态数据统计", notes = "退款订单状态数据统计", produces = "text/plain")
    @PreAuthorize("hasRole('user-refund-info-query')")
    @GetMapping("/v1/refund/info/count")
    public JSONResult<VerifyPageTotal> getRefundInfoCount(RefundInfoQueryParam param) {
        VerifyPageTotal verifyPageResult = new VerifyPageTotal();
        if (null != param.getAccount()) {
            param.setMemberId(memberService.findMemberIdByPhone(param.getAccount()));
        }
        if (null != param.getActivityName()) {
            param.setActivityId(activityService.getActivityByName(param.getActivityName()));
        }
        verifyPageResult.setTotalCount(refundInfoService.count(param));
        param.setVerify(SystemConst.VERIFY_AWAIT);
        verifyPageResult.setVerifyAwaitCount(refundInfoService.count(param));
        param.setVerify(SystemConst.VERIFY_ADOPT);
        verifyPageResult.setVerifyAdoptCount(refundInfoService.count(param));
        param.setVerify(SystemConst.VERIFY_REJECT);
        verifyPageResult.setVerifyRejectCount(refundInfoService.count(param));
        return JSONResult.ok(verifyPageResult);
    }

    @ApiOperation(value = "审核退款订单信息", notes = "审核退款订单信息", produces = "text/plain")
    @PostMapping("/v1/refund/verify/info/{id}")
    @PreAuthorize("hasRole('user-refund-info-verify-edit-v1')")
    @AOLog
    @EditAlertLayout
    public JSONResult refundInfoVerifyV1(@PathVariable Long id, @Valid @RequestBody RefundInfoParam param) {
        refundInfoService.refundVerify(id, param.getVerify(), param.getVerifyRemark());
        return JSONResult.ok();
    }


}