package com.izouma.nineth.web;

import com.izouma.nineth.converter.LongArrayConverter;
import com.izouma.nineth.domain.MintActivity;
import com.izouma.nineth.domain.MintMaterial;
import com.izouma.nineth.domain.MintOrder;
import com.izouma.nineth.dto.MintOrderDTO;
import com.izouma.nineth.dto.PageQuery;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.repo.MintActivityRepo;
import com.izouma.nineth.repo.MintMaterialRepo;
import com.izouma.nineth.repo.MintOrderRepo;
import com.izouma.nineth.service.MintOrderService;
import com.izouma.nineth.utils.ObjUtils;
import com.izouma.nineth.utils.SecurityUtils;
import com.izouma.nineth.utils.excel.ExcelUtils;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/mintOrder")
@AllArgsConstructor
public class MintOrderController extends BaseController {
    private MintOrderService mintOrderService;
    private MintOrderRepo    mintOrderRepo;
    private MintActivityRepo mintActivityRepo;
    private MintMaterialRepo mintMaterialRepo;

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/save")
    public MintOrder save(@RequestBody MintOrder record) {
        if (record.getId() != null) {
            MintOrder orig = mintOrderRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
            ObjUtils.merge(orig, record);
            return mintOrderRepo.save(orig);
        }
        return mintOrderRepo.save(record);
    }


    //@PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/all")
    public Page<MintOrder> all(@RequestBody PageQuery pageQuery) {
        Page<MintOrder> all = mintOrderService.all(pageQuery);
        Set<Long> mids = all.map(MintOrder::getMintActivityId).stream().collect(Collectors.toSet());
        List<Long> ids = all.map(MintOrder::getId).stream().collect(Collectors.toList());
        Map<Long, String> activityMap = mintActivityRepo.findAllByIdInAndDelFalse(mids)
                .stream()
                .collect(Collectors.toMap(MintActivity::getId, MintActivity::getName));
        Map<Long, List<MintMaterial>> materialMap = mintMaterialRepo.findAllByOrderIdInAndDelFalse(ids)
                .stream()
                .collect(Collectors.groupingBy(MintMaterial::getOrderId));
        return all.map(mintOrder -> {
            mintOrder.setMintActivity(activityMap.get(mintOrder.getMintActivityId()));
            mintOrder.setMaterial(materialMap.get(mintOrder.getId()));
            return mintOrder;
        });
    }

    @GetMapping("/get/{id}")
    public MintOrder get(@PathVariable Long id) {
        MintOrder mintOrder = mintOrderRepo.findById(id).orElseThrow(new BusinessException("无记录"));
        if (!Objects.isNull(mintOrder.getMintActivityId())) {
            mintActivityRepo.findByIdAndDelFalse(mintOrder.getMintActivityId())
                    .ifPresent(activity -> mintOrder.setMintActivity(activity.getName()));
        }
        mintOrder.setMaterial(mintMaterialRepo.findAllByOrderIdAndDelFalse(id));
        return mintOrder;
    }

    @PreAuthorize("hasRole('ADMIN')")
    @PostMapping("/del/{id}")
    public void del(@PathVariable Long id) {
        mintOrderRepo.softDelete(id);
    }

    @GetMapping("/excel")
    @ResponseBody
    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
        List<MintOrder> data = all(pageQuery).getContent();
        ExcelUtils.export(response, data);
    }

    @PostMapping("/create")
    public MintOrder create(@RequestParam String assets, @RequestParam Long mintActivityId, Long addressId) {
        LongArrayConverter lc = new LongArrayConverter();
        List<Long> assetIds = lc.convertToEntityAttribute(assets);
        return mintOrderService.create(SecurityUtils.getAuthenticatedUser(), assetIds, mintActivityId, addressId);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("导出")
    @PostMapping("/excelPhone")
    public void excelPhone(HttpServletResponse response, @RequestBody PageQuery pageQuery) throws IOException {
        List<MintOrderDTO> data = all(pageQuery).map(MintOrderDTO::new).getContent();
        ExcelUtils.export(response, data);
    }

    @PreAuthorize("hasRole('ADMIN')")
    @ApiOperation("订单完成")
    @GetMapping("/finish/{id}")
    public void finish(@PathVariable Long id) {
        mintOrderService.finish(id);
    }

    @ApiOperation("订单发货")
    @GetMapping("/delivery")
    public void delivery(@RequestParam Long id, @RequestParam String courierId) {
        mintOrderService.dispatch(id, courierId);
    }

    @GetMapping("/{id}/status")
    public Object status(@PathVariable Long id) {
        MintOrder order = mintOrderRepo.findById(id).orElseThrow(new BusinessException("订单不存在"));
        return new HashMap<>() {{
            put("status", order.getStatus());
        }};
    }

    @PreAuthorize("hasAnyRole('ADMIN')")
    @PostMapping("/pass")
    public void audit(@RequestParam Long id) {
        mintOrderService.orderAudit(id, true);
    }

    @PreAuthorize("hasAnyRole('ADMIN')")
    @PostMapping("/deny")
    public void deny(@RequestParam Long id) {
        mintOrderService.orderAudit(id, false);
    }

}

