package com.starry.admin.modules.weichat.controller;

import cn.hutool.core.collection.CollUtil;
import com.starry.admin.common.aspect.ClerkUserLogin;
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.clerk.enums.ClerkMediaReviewState;
import com.starry.admin.modules.clerk.enums.ClerkMediaUsage;
import com.starry.admin.modules.clerk.module.entity.PlayClerkMediaAssetEntity;
import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
import com.starry.admin.modules.clerk.service.IPlayClerkMediaAssetService;
import com.starry.admin.modules.media.entity.PlayMediaEntity;
import com.starry.admin.modules.media.enums.MediaOwnerType;
import com.starry.admin.modules.media.service.IPlayMediaService;
import com.starry.admin.modules.weichat.assembler.ClerkMediaAssembler;
import com.starry.admin.modules.weichat.entity.clerk.MediaOrderRequest;
import com.starry.admin.modules.weichat.entity.clerk.MediaVo;
import com.starry.admin.modules.weichat.service.MediaUploadService;
import com.starry.common.result.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Api(tags = "店员媒资接口")
@RestController
@RequestMapping("/wx/clerk/media")
@Validated
@RequiredArgsConstructor
public class WxClerkMediaController {

    private final MediaUploadService mediaUploadService;
    private final IPlayMediaService mediaService;
    private final IPlayClerkMediaAssetService clerkMediaAssetService;

    @ApiOperation("上传媒资（图片/视频）")
    @PostMapping("/upload")
    @ClerkUserLogin
    public R upload(@RequestParam("file") MultipartFile file,
            @RequestParam(value = "usage", required = false) String usageCode) {
        PlayClerkUserInfoEntity clerkInfo = requireClerkInfo();
        MediaVo vo = mediaUploadService.upload(file, clerkInfo, ClerkMediaUsage.fromCode(usageCode));
        return R.ok(vo);
    }

    @ApiOperation("更新媒资顺序并提交保留列表")
    @PutMapping("/order")
    @ClerkUserLogin
    public R updateOrder(@Valid @RequestBody MediaOrderRequest request) {
        PlayClerkUserInfoEntity clerkInfo = requireClerkInfo();
        ClerkMediaUsage usage = ClerkMediaUsage.fromCode(request.getUsage());
        List<String> mediaIds = CollUtil.isEmpty(request.getMediaIds()) ? Collections.emptyList()
                : request.getMediaIds().stream().distinct().collect(Collectors.toList());
        clerkMediaAssetService.submitWithOrder(clerkInfo.getId(), usage, mediaIds);
        return R.ok();
    }

    @ApiOperation("删除媒资（软删除）")
    @DeleteMapping("/{id}")
    @ClerkUserLogin
    public R delete(@PathVariable("id") String mediaId) {
        PlayClerkUserInfoEntity clerkInfo = requireClerkInfo();
        clerkMediaAssetService.softDelete(clerkInfo.getId(), mediaId);
        mediaService.softDelete(MediaOwnerType.CLERK, clerkInfo.getId(), mediaId);
        return R.ok();
    }

    @ApiOperation("查询草稿媒资列表")
    @GetMapping("/list")
    @ClerkUserLogin
    public R listDraft(@RequestParam(value = "usage", required = false) String usageCode) {
        PlayClerkUserInfoEntity clerkInfo = requireClerkInfo();
        ClerkMediaUsage usage = ClerkMediaUsage.fromCode(usageCode);
        List<PlayClerkMediaAssetEntity> assets = clerkMediaAssetService.listByState(clerkInfo.getId(), usage,
                Arrays.asList(ClerkMediaReviewState.DRAFT, ClerkMediaReviewState.PENDING,
                        ClerkMediaReviewState.REJECTED));
        Map<String, PlayMediaEntity> mediaMap = loadMediaMap(assets);
        return R.ok(ClerkMediaAssembler.toVoList(assets, mediaMap));
    }

    @ApiOperation("查询已审核通过的媒资")
    @GetMapping("/approved")
    @ClerkUserLogin
    public R listApproved(@RequestParam(value = "usage", required = false) String usageCode) {
        PlayClerkUserInfoEntity clerkInfo = requireClerkInfo();
        ClerkMediaUsage usage = ClerkMediaUsage.fromCode(usageCode);
        List<PlayClerkMediaAssetEntity> assets = clerkMediaAssetService.listByState(clerkInfo.getId(), usage,
                Collections.singletonList(ClerkMediaReviewState.APPROVED));
        Map<String, PlayMediaEntity> mediaMap = loadMediaMap(assets);
        return R.ok(ClerkMediaAssembler.toVoList(assets, mediaMap));
    }

    private PlayClerkUserInfoEntity requireClerkInfo() {
        PlayClerkUserInfoEntity clerk = ThreadLocalRequestDetail.getClerkUserInfo();
        if (clerk == null) {
            throw new CustomException("店员未登录");
        }
        return clerk;
    }

    private Map<String, PlayMediaEntity> loadMediaMap(List<PlayClerkMediaAssetEntity> assets) {
        if (CollUtil.isEmpty(assets)) {
            return Collections.emptyMap();
        }
        List<String> mediaIds = assets.stream().map(PlayClerkMediaAssetEntity::getMediaId).distinct()
                .collect(Collectors.toList());
        List<PlayMediaEntity> mediaList = mediaService.listByIds(mediaIds);
        if (CollUtil.isEmpty(mediaList)) {
            return Collections.emptyMap();
        }
        return mediaList.stream().collect(Collectors.toMap(PlayMediaEntity::getId, item -> item));
    }
}
