package com.yonge.cooleshow.admin.controller;

import com.alibaba.fastjson.JSON;
import com.dayaedu.cbs.openfeign.client.MusicFeignClientService;
import com.dayaedu.cbs.openfeign.wrapper.music.CbsSubjectWrapper;
import com.dayaedu.cbs.openfeign.wrapper.musicInstrument.CbsMusicalInstrumentWrapper;
import com.microsvc.toolkit.common.webportal.exception.BizException;
import com.yonge.cooleshow.biz.dal.dto.PageUtil;
import com.yonge.cooleshow.biz.dal.entity.Subject;
import com.yonge.cooleshow.biz.dal.queryInfo.SubjectQueryInfo;
import com.yonge.cooleshow.biz.dal.service.SubjectService;
import com.yonge.cooleshow.biz.dal.service.SysUserService;
import com.yonge.cooleshow.biz.dal.wrapper.InstrumentWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.SubjectWrapper;
import com.yonge.cooleshow.common.controller.BaseController;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.toolset.base.page.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RequestMapping("${app-config.url.admin:}/subject")
@Api(tags = "声部服务")
@RestController
@Slf4j
public class SubjectController extends BaseController {

	@Autowired
	private SubjectService subjectService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private MusicFeignClientService musicFeignClientService;

	@ApiOperation(value = "根据声部编号查询声部")
	@GetMapping("/get/{id}")
	@PreAuthorize("@pcs.hasPermissions('subject/get')")
	public HttpResponseResult<Subject> get(@ApiParam(value = "声部编号", required = true) @PathVariable("id") Long id) {
		return succeed(subjectService.get(id));
	}

	@ApiOperation(value = "分页查询声部列表")
	@PostMapping("/queryPage")
	@PreAuthorize("@pcs.hasPermissions('subject/queryPage')")
	public HttpResponseResult<PageInfo<SubjectWrapper.Subject>> queryPage(@RequestBody SubjectWrapper.SubjectQuery query) {
		return succeed(subjectService.selectPage(query));
	}

	@ApiOperation(value = "分页查询声部树状列表")
	@GetMapping("/queryPageTree")
	@PreAuthorize("@pcs.hasPermissions('subject/queryPageTree')")
	public HttpResponseResult<PageInfo<Subject>> queryPageTree(SubjectQueryInfo queryInfo) {
		return succeed(subjectService.queryPageTree(queryInfo));
	}

	@ApiOperation(value = "新增声部")
	@PostMapping("/upset")
	@PreAuthorize("@pcs.hasPermissions('subject/upset')")
	public Object update(@RequestBody SubjectWrapper.AddSubject add) {
		add.setOperator(sysUserService.getUserId());
		subjectService.add(add);
		return succeed();
	}

	@ApiOperation(value = "修改分类名称")
	@PostMapping("/updateCategoryName")
	@PreAuthorize("@pcs.hasPermissions('subject/updateCategoryName')")
	public HttpResponseResult<Object> updateCategoryName(@RequestBody Subject subject) {
		Subject s = subjectService.get(subject.getId());
		s.setName(subject.getName());
		subjectService.update(s);
		return succeed();
	}

	@ApiOperation(value = "修改分类")
	@PostMapping("/updateCategory")
	@PreAuthorize("@pcs.hasPermissions('subject/updateCategory')")
	public HttpResponseResult<Object> updateCategory(@RequestBody Subject subject) {
		Subject s = subjectService.get(subject.getId());
		s.setParentSubjectId(subject.getParentSubjectId());
		subjectService.update(s);
		return succeed();
	}

	@PreAuthorize("@pcs.hasPermissions('subject/enable')")
	@PostMapping("/enable")
	public HttpResponseResult<Boolean> enable(@RequestBody SubjectWrapper.SubjectEnable subjectEnable) {
		Subject subject = new Subject();
		subject.setId(subjectEnable.getId());
		subject.setEnableFlag(subjectEnable.getEnableFlag());
		return succeed(subjectService.enable(subject));
	}

    /**
     * 声部分页
     */
    @ApiOperation(value = "内容平台对应的声部数据")
    @PostMapping("/cbsSubject/page")
    public HttpResponseResult<List<SubjectWrapper.CbsSubject>> subjectPage(@RequestBody SubjectWrapper.CbsSubjectQuery query){
		// 移除已被使用的声部ID
		if (Boolean.TRUE.equals(query.getRemoveUsed())) {
			List<Subject> list = subjectService.getDao().notInSubjectIds(query.getSubjectId());
			if (CollectionUtils.isNotEmpty(list)) {
				List<Long> cbsSubjectIds = list.stream().map(Subject::getCbsSubjectId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
				if (CollectionUtils.isNotEmpty(cbsSubjectIds)) {
					query.setRemoveIds(cbsSubjectIds);
				}
			}
		}

		try {
			query.setPage(1);
			query.setRows(-1);
			List<CbsSubjectWrapper.Subject> subjectPageInfo = musicFeignClientService.subjectPage(query).feignData().getRows();
			if (CollectionUtils.isEmpty(subjectPageInfo)) {
				return succeed(new ArrayList<>());
			}
			List<Integer> subjectIds = subjectPageInfo.stream().map(CbsSubjectWrapper.Subject::getId).map(Long::intValue).collect(Collectors.toList());

			// 查询乐器信息
			CbsMusicalInstrumentWrapper.MusicalInstrumentQuery musicalInstrumentQuery = new CbsMusicalInstrumentWrapper.MusicalInstrumentQuery();
			musicalInstrumentQuery.setSubjectIds(subjectIds);
			musicalInstrumentQuery.setPage(1);
			musicalInstrumentQuery.setRows(9999);
			List<CbsMusicalInstrumentWrapper.MusicalInstrumentQueryDto> rows = musicFeignClientService
					.musicalInstrumentPage(musicalInstrumentQuery).feignData().getRows();
			Map<Long, List<CbsMusicalInstrumentWrapper.MusicalInstrumentQueryDto>> subjectIdMap = rows.stream()
					.collect(Collectors.groupingBy(o -> o.getSubjectId().longValue(), LinkedHashMap::new, Collectors.toList()));

			// 查询本地已经添加过的曲目数据
			SubjectWrapper.SubjectQuery query1 = new SubjectWrapper.SubjectQuery();
			query1.setHasInstrument(true);
			List<SubjectWrapper.Subject> list = subjectService.list(query1);
			// 转map
			Map<Long, SubjectWrapper.Subject> subjectMap = list.stream().collect(Collectors.groupingBy(e -> e.getCbsSubjectId(), Collectors.collectingAndThen(Collectors.toList(), v -> v.get(0))));

			List<SubjectWrapper.CbsSubject> cbsSubjects = new ArrayList<>();
			for (CbsSubjectWrapper.Subject subject : subjectPageInfo) {
				SubjectWrapper.CbsSubject cbsSubject = new SubjectWrapper.CbsSubject();
				BeanUtils.copyProperties(subject, cbsSubject);

				List<CbsMusicalInstrumentWrapper.MusicalInstrumentQueryDto> musicalInstrumentQueryDtos = subjectIdMap.get(cbsSubject.getId());
				if (CollectionUtils.isEmpty(musicalInstrumentQueryDtos)) {
					continue;
				}
				cbsSubject.setInstruments(JSON.parseArray(JSON.toJSONString(musicalInstrumentQueryDtos), SubjectWrapper.Instrument.class));

				cbsSubjects.add(cbsSubject);
				// 本地已经添加过的曲目数据
				SubjectWrapper.Subject subject1 = subjectMap.get(subject.getId());
				if (subject1 == null) {
					continue;
				}
				List<InstrumentWrapper.Instrument> instruments = subject1.getInstruments();
				if (CollectionUtils.isEmpty(instruments)) {
					continue;
				}
				// instruments 转map
				Map<Long, InstrumentWrapper.Instrument> instrumentMap = instruments.stream().collect(Collectors.toMap(InstrumentWrapper.Instrument::getId, o -> o));
				for (SubjectWrapper.Instrument instrument : cbsSubject.getInstruments()) {
					instrument.setAdded(instrumentMap.containsKey(instrument.getId().longValue()));
				}

			}

			return succeed(cbsSubjects);
		} catch (Exception e) {
			log.error("内容平台对应的声部数据查询失败", e);
			throw BizException.from("内容平台服务异常");
		}
    }

	@ApiOperation(value = "内容平台对应的声部数据")
	@PostMapping("/cbsSubject/list")
	public HttpResponseResult<PageInfo<CbsSubjectWrapper.Subject>> subjectPage(){
		CbsSubjectWrapper.SubjectQuery subjectQuery = new CbsSubjectWrapper.SubjectQuery();
		subjectQuery.setPage(1);
		subjectQuery.setRows(-1);

		try {
			return succeed(PageUtil.pageInfo(musicFeignClientService.subjectPage(subjectQuery).feignData()));
		} catch (Exception e) {
			log.error("内容平台对应的声部数据查询失败", e);
			throw BizException.from("内容平台服务异常");
		}
	}
}
