package com.bizzan.bitrade.controller.system;

import com.alibaba.fastjson.JSON;
import com.bizzan.bitrade.annotation.AccessLog;
import com.bizzan.bitrade.constant.AdminModule;
import com.bizzan.bitrade.constant.AnnouncementClassification;
import com.bizzan.bitrade.constant.PageModel;
import com.bizzan.bitrade.controller.BaseController;
import com.bizzan.bitrade.entity.Announcement;
import com.bizzan.bitrade.entity.QAnnouncement;
import com.bizzan.bitrade.pagination.PageResult;
import com.bizzan.bitrade.service.AnnouncementService;
import com.bizzan.bitrade.service.LocaleMessageSourceService;
import com.bizzan.bitrade.util.MessageResult;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;

import lombok.extern.slf4j.Slf4j;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;


/**
 * @author
 * @description 公告
 * @date 2019/3/5 15:25
 */
@Slf4j
@RestController
@RequestMapping("system/announcement")
public class AnnouncementController extends BaseController {
    @Autowired
    private AnnouncementService announcementService;
    @Autowired
    private LocaleMessageSourceService messageSource;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    @RequiresPermissions("system:announcement:create")
    @PostMapping("create")
    public MessageResult create(
            @RequestParam String title,
            @RequestParam String content,
            @RequestParam AnnouncementClassification announcementClassification,
            @RequestParam("isShow") Boolean isShow,
            @RequestParam("isPopup") Boolean isPopup,
            @RequestParam(value = "imgUrl", required = false) String imgUrl,
            @RequestParam(value = "publishTime", required = false)
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date publishTime) {
        Announcement announcement = new Announcement();
        announcement.setTitle(title);
        announcement.setContent(content);
        announcement.setIsShow(isShow);
        announcement.setIsPopup(isPopup);
        announcement.setAnnouncementClassification(announcementClassification);
        announcement.setImgUrl(imgUrl);
        announcement.setIsTop("1");
        announcement.setPublishTime(publishTime != null ? publishTime : new Date());
        announcementService.save(announcement);

        if (announcement.getIsShow() &&
                (announcement.getAnnouncementClassification() == AnnouncementClassification.CONTRACT
                        || announcement.getAnnouncementClassification() == AnnouncementClassification.SYSTEM)) {
            kafkaTemplate.send("announcement-send", JSON.toJSONString(announcement));
        }

        return success(messageSource.getMessage("SUCCESS"));
    }

    @RequiresPermissions("system:announcement:top")
    @PostMapping("top")
    @AccessLog(module = AdminModule.CMS, operation = "公告置顶")
    public MessageResult toTop(@RequestParam("id") long id) {
        Announcement announcement = announcementService.findById(id);
        int a = announcementService.getMaxSort();
        announcement.setSort(a + 1);
        announcement.setIsTop("0");
        announcementService.save(announcement);
        return success(messageSource.getMessage("SUCCESS"));
    }

    @RequiresPermissions("system:announcement:dwon")
    @PostMapping("down")
    @AccessLog(module = AdminModule.CMS, operation = "公告取消置顶")
    public MessageResult toDown(@RequestParam("id") long id) {
        Announcement announcement = announcementService.findById(id);
        announcement.setIsTop("1");
        announcementService.save(announcement);
        return success();
    }

    @RequiresPermissions("system:announcement:page-query")
    @GetMapping("page-query")
    public MessageResult page(
            PageModel pageModel,
            @RequestParam(required = false) Boolean isShow,
            @RequestParam(required = false) String title,
            @RequestParam(required = false) Integer announcementClassification,
            @RequestParam(required = false) Boolean isPopup) {
        ArrayList<Predicate> predicates = new ArrayList<>();
        if (isShow != null) {
            predicates.add(QAnnouncement.announcement.isShow.eq(isShow));
        }
        if (!StringUtils.isEmpty(title)) {
            predicates.add(QAnnouncement.announcement.title.containsIgnoreCase(title.trim()));
        }
        if (announcementClassification != null) {
            AnnouncementClassification[] classValues = AnnouncementClassification.values();
            if (announcementClassification >= 0 && announcementClassification < classValues.length) {
                predicates.add(QAnnouncement.announcement.announcementClassification
                        .eq(classValues[announcementClassification]));
            }
        }
        if (isPopup != null) {
            predicates.add(QAnnouncement.announcement.isPopup.eq(isPopup));
        }

        ArrayList<OrderSpecifier> orderSpecifiers = new ArrayList<>();
        orderSpecifiers.add(QAnnouncement.announcement.isTop.asc());
        orderSpecifiers.add(QAnnouncement.announcement.sort.desc());
        orderSpecifiers.add(QAnnouncement.announcement.id.desc());

        PageResult<Announcement> result = announcementService.queryDsl(
                pageModel.getPageNo(), pageModel.getPageSize(),
                predicates, QAnnouncement.announcement, orderSpecifiers);
        return success(result);
    }

    @RequiresPermissions("system:announcement:deletes")
    @PatchMapping("deletes")
    public MessageResult deleteOne(@RequestParam("ids") Long[] ids) {
        announcementService.deleteBatch(ids);
        return success();
    }

    @RequiresPermissions("system:announcement:detail")
    @GetMapping("{id}/detail")
    public MessageResult detail(@PathVariable Long id) {
        Announcement announcement = announcementService.findById(id);
        Assert.notNull(announcement, "validate id!");
        return success(announcement);
    }

    @RequiresPermissions("system:announcement:update")
    @PutMapping("{id}/update")
    public MessageResult update(
            @PathVariable Long id,
            @RequestParam String title,
            @RequestParam String content,
            @RequestParam Boolean isShow,
            @RequestParam Boolean isPopup,
            @RequestParam AnnouncementClassification announcementClassification,
            @RequestParam(value = "imgUrl", required = false) String imgUrl,
            @RequestParam(value = "publishTime", required = false)
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date publishTime) {
        Announcement announcement = announcementService.findById(id);
        Assert.notNull(announcement, "validate id!");
        announcement.setTitle(title);
        announcement.setContent(content);
        announcement.setIsShow(isShow);
        announcement.setIsPopup(isPopup);
        announcement.setAnnouncementClassification(announcementClassification);
        announcement.setImgUrl(imgUrl);
        if (publishTime != null) {
            announcement.setPublishTime(publishTime);
        }
        announcementService.save(announcement);

        if (announcement.getAnnouncementClassification() == AnnouncementClassification.CONTRACT
                || announcement.getAnnouncementClassification() == AnnouncementClassification.SYSTEM) {
            kafkaTemplate.send("announcement-send", JSON.toJSONString(announcement));
            log.info("kafkaTemplate.send={}", AnnouncementClassification.CONTRACT);
        }

        return success();
    }

    @RequiresPermissions("system:announcement:turn-off")
    @PatchMapping("{id}/turn-off")
    public MessageResult turnOff(@PathVariable Long id) {
        Announcement announcement = announcementService.findById(id);
        Assert.notNull(announcement, "validate id!");
        announcement.setIsShow(false);
        announcementService.save(announcement);
        return success();
    }

    @RequiresPermissions("system:announcement:turn-on")
    @PatchMapping("{id}/turn-on")
    public MessageResult turnOn(@PathVariable("id") Long id) {
        Announcement announcement = announcementService.findById(id);
        Assert.notNull(announcement, "validate id!");
        announcement.setIsShow(true);
        announcementService.save(announcement);
        return success();
    }

    @RequiresPermissions("system:announcement:popup-on")
    @PatchMapping("{id}/popup-on")
    public MessageResult popupOn(@PathVariable("id") Long id) {
        Announcement announcement = announcementService.findById(id);
        Assert.notNull(announcement, "validate id!");
        announcement.setIsPopup(true);
        announcementService.save(announcement);
        return success();
    }

    @RequiresPermissions("system:announcement:popup-off")
    @PatchMapping("{id}/popup-off")
    public MessageResult popupOff(@PathVariable("id") Long id) {
        Announcement announcement = announcementService.findById(id);
        Assert.notNull(announcement, "validate id!");
        announcement.setIsPopup(false);
        announcementService.save(announcement);
        return success();
    }

}
