package com.liquidnet.client.admin.web.controller.zhengzai.goblin.artist;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.liquidnet.client.admin.common.annotation.Log;
import com.liquidnet.client.admin.common.core.controller.BaseController;
import com.liquidnet.client.admin.common.core.domain.AjaxResult;
import com.liquidnet.client.admin.common.core.page.TableDataInfo;
import com.liquidnet.client.admin.common.enums.BusinessType;
import com.liquidnet.client.admin.zhengzai.goblin.service.IGoblinArtistTopicAdminService;
import com.liquidnet.service.goblin.entity.GoblinArtistTopic;
import com.liquidnet.service.goblin.entity.GoblinStoreInfo;
import com.liquidnet.service.goblin.mapper.GoblinStoreInfoMapper;
import com.liquidnet.service.kylin.entity.KylinArtist;
import com.liquidnet.service.kylin.mapper.KylinArtistMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.liquidnet.client.admin.web.controller.zhengzai.goblin.artist.ArtistAdminHelper.*;

@Controller
@RequestMapping("goblin/artist/topic")
public class GoblinArtistTopicAdminController extends BaseController {
    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private final String prefix = "zhengzai/goblin/artist/topic";

    @Autowired
    private IGoblinArtistTopicAdminService topicAdminService;
    @Autowired
    private KylinArtistMapper kylinArtistMapper;
    @Autowired
    private GoblinStoreInfoMapper storeInfoMapper;

    @GetMapping()
    public String index() {
        return prefix + "/topic";
    }

    @RequiresPermissions("goblin:artist:topic:list")
    @RequestMapping("/list")
    @ResponseBody
    public TableDataInfo list(GoblinArtistTopic topic,
                              @RequestParam(required = false) String artistName,
                              @RequestParam(required = false) String storeName) {
        LambdaQueryWrapper<GoblinArtistTopic> qw = Wrappers.lambdaQuery(GoblinArtistTopic.class);
        qw.eq(GoblinArtistTopic::getDelFlg, 0);

        if (topic.getStatus() != null) {
            qw.eq(GoblinArtistTopic::getStatus, topic.getStatus());
        }
        if (StringUtils.isNotBlank(topic.getTopicName())) {
            qw.like(GoblinArtistTopic::getTopicName, topic.getTopicName());
        }
        List<String> sids = findStoreIds(storeInfoMapper, storeName);
        if (sids != null) {
            if (sids.isEmpty()) return getDataTable(Collections.emptyList());
            qw.in(GoblinArtistTopic::getStoreId, sids);
        }
        List<String> aids = findArtistIds(kylinArtistMapper, artistName);
        if (aids != null) {
            if (aids.isEmpty()) return getDataTable(Collections.emptyList());
            qw.in(GoblinArtistTopic::getArtistId, aids);
        }
        qw.orderByAsc(GoblinArtistTopic::getSort);
        qw.orderByDesc(GoblinArtistTopic::getCreatedAt);
        startPage();
        return getDataTable(withNames(topicAdminService.list(qw)));
    }

    private List<Map<String, Object>> withNames(List<GoblinArtistTopic> list) {
        if (list.isEmpty()) return Collections.emptyList();
        Map<String, String> storeNames = storeNameMap(storeInfoMapper, idsOf(list, GoblinArtistTopic::getStoreId));
        Map<String, String> artistNames = artistNameMap(kylinArtistMapper, idsOf(list, GoblinArtistTopic::getArtistId));
        Map<String, Integer> goodsCounts = topicAdminService.goodsCountMap(idsOf(list, GoblinArtistTopic::getTopicId));

        return list.stream().map(item -> {
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("topicId", item.getTopicId());
            row.put("topicName", item.getTopicName());
            row.put("artistId", item.getArtistId());
            row.put("artistName", artistNames.get(item.getArtistId()));
            row.put("storeId", item.getStoreId());
            row.put("storeName", storeNames.get(item.getStoreId()));
            row.put("status", item.getStatus());
            row.put("sort", item.getSort());
            row.put("recommendPosition", item.getRecommendPosition());
            row.put("goodsCount", goodsCounts.getOrDefault(item.getTopicId(), 0));
            row.put("createdAt", formatTime(item.getCreatedAt()));
            row.put("onSaleStart", formatDate(item.getOnSaleStart()));
            row.put("onSaleEnd", formatDate(item.getOnSaleEnd()));
            return row;
        }).collect(Collectors.toList());
    }

    private static String formatDate(LocalDateTime time) {
        return time != null ? time.format(DATE_FMT) : null;
    }

    @RequiresPermissions("goblin:artist:topic:info")
    @GetMapping("detail/{topicId}")
    public String detail(@PathVariable String topicId, ModelMap mmap) {
        Map<String, Object> topic = topicAdminService.topicDetail(topicId);
        if (topic == null) {
            return prefix + "/topic";
        }
        mmap.put("topic", formatDetailTime(topic));

        String artistId = (String) topic.get("artistId");
        if (StringUtils.isNotBlank(artistId)) {
            KylinArtist artist = kylinArtistMapper.selectOne(
                    new LambdaQueryWrapper<KylinArtist>()
                            .eq(KylinArtist::getArtistId, artistId).last("limit 1"));
            mmap.put("artist", artist);
        }

        String storeId = (String) topic.get("storeId");
        if (StringUtils.isNotBlank(storeId)) {
            mmap.put("store", storeInfoMapper.selectOne(
                    new LambdaQueryWrapper<GoblinStoreInfo>()
                            .eq(GoblinStoreInfo::getStoreId, storeId).last("limit 1")));
        }

        return prefix + "/detail";
    }

    private Map<String, Object> formatDetailTime(Map<String, Object> topic) {
        Map<String, Object> copy = new LinkedHashMap<>(topic);
        copy.put("createdAt", formatTime((LocalDateTime) copy.get("createdAt")));
        copy.put("onSaleStart", formatTime((LocalDateTime) copy.get("onSaleStart")));
        copy.put("onSaleEnd", formatTime((LocalDateTime) copy.get("onSaleEnd")));
        return copy;
    }

    @Log(title = "艺人专题:设置排序", businessType = BusinessType.UPDATE)
    @RequiresPermissions("goblin:artist:topic:sort")
    @PostMapping("sort")
    @ResponseBody
    public AjaxResult setSort(@RequestParam String topicId, @RequestParam int sort) {
        return toAjax(topicAdminService.setSort(topicId, sort));
    }

    @Log(title = "艺人专题:设置推荐位", businessType = BusinessType.UPDATE)
    @RequiresPermissions("goblin:artist:topic:recommend")
    @PostMapping("recommend")
    @ResponseBody
    public AjaxResult setRecommend(@RequestParam String topicId, @RequestParam int position) {
        return toAjax(topicAdminService.setRecommend(topicId, position));
    }

    /** 查询推荐位当前占用专题（用于替换确认提示） */
    @RequiresPermissions("goblin:artist:topic:recommend")
    @GetMapping("recommendOwner")
    @ResponseBody
    public AjaxResult recommendOwner(@RequestParam int position) {
        if (position <= 0) {
            return AjaxResult.success();
        }
        GoblinArtistTopic owner = topicAdminService.getOne(new LambdaQueryWrapper<GoblinArtistTopic>()
                .eq(GoblinArtistTopic::getRecommendPosition, position)
                .eq(GoblinArtistTopic::getDelFlg, 0)
                .last("limit 1"));
        if (owner == null) {
            return AjaxResult.success();
        }
        Map<String, Object> data = new LinkedHashMap<>();
        data.put("topicId", owner.getTopicId());
        data.put("topicName", owner.getTopicName());
        return AjaxResult.success(data);
    }

    @Log(title = "艺人专题:上下架", businessType = BusinessType.UPDATE)
    @RequiresPermissions("goblin:artist:topic:status")
    @PostMapping("status")
    @ResponseBody
    public AjaxResult setStatus(@RequestParam String topicId, @RequestParam int status) {
        return toAjax(topicAdminService.setStatus(topicId, status));
    }

    @Log(title = "艺人专题:删除", businessType = BusinessType.DELETE)
    @RequiresPermissions("goblin:artist:topic:delete")
    @PostMapping("delete")
    @ResponseBody
    public AjaxResult deleteTopic(@RequestParam String topicId) {
        return toAjax(topicAdminService.deleteTopic(topicId));
    }
}
