package mingzuozhibi.action;

import mingzuozhibi.persist.Disc;
import mingzuozhibi.persist.Sakura;
import mingzuozhibi.support.Dao;
import mingzuozhibi.support.JsonArg;
import org.hibernate.criterion.Restrictions;
import org.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static mingzuozhibi.persist.Sakura.ViewType.SakuraList;

@RestController
public class SakuraController extends BaseController {

    @Autowired
    private Dao dao;

    @Transactional
    @GetMapping(value = "/api/sakuras", produces = MEDIA_TYPE)
    public String listSakura(@RequestParam("discColumns") String discColumns) {
        JSONArray data = new JSONArray();

        @SuppressWarnings("unchecked")
        List<Sakura> sakuras = dao.query(session -> {
            return session.createCriteria(Sakura.class)
                    .add(Restrictions.eq("viewType", SakuraList))
                    .add(Restrictions.eq("enabled", true))
                    .list();
        });

        Set<String> columns = Arrays.stream(discColumns.split(",")).collect(Collectors.toSet());
        sakuras.forEach(sakura -> {
            data.put(sakura.toJSON().put("discs", buildDiscs(sakura, columns)));
        });
        if (LOGGER.isDebugEnabled()) {
            debugRequest("[size={}][discColumns={}]", sakuras.size(), discColumns);
        }
        return objectResult(data);
    }

    @Transactional
    @GetMapping(value = "/api/basic/sakuras", produces = MEDIA_TYPE)
    public String listBasicSakura() {
        JSONArray array = new JSONArray();
        dao.findAll(Sakura.class).forEach(sakura -> array.put(sakura.toJSON()));

        if (LOGGER.isDebugEnabled()) {
            debugRequest("[size={}]", array.length());
        }
        return objectResult(array);
    }

    @Transactional
    @PostMapping(value = "/api/basic/sakuras", produces = MEDIA_TYPE)
    public String saveBasicSakura(
            @JsonArg("$.key") String key,
            @JsonArg("$.title") String title,
            @JsonArg("$.viewType") String viewType) {
        if (dao.lookup(Sakura.class, "key", key) != null) {
            return errorMessage("该Sakura列表已存在");
        }
        Sakura sakura = new Sakura(key, title, Sakura.ViewType.valueOf(viewType));
        dao.save(sakura);

        if (LOGGER.isInfoEnabled()) {
            infoRequest("[json={}]", sakura.toJSON());
        }
        return objectResult(sakura.toJSON());
    }

    private JSONArray buildDiscs(Sakura sakura, Set<String> columns) {
        JSONArray discs = new JSONArray();
        sakura.getDiscs().stream()
                .filter(disc -> disc.getUpdateType() != Disc.UpdateType.None)
                .forEach(disc -> discs.put(disc.toJSON(columns)));
        return discs;
    }

    @Transactional
    @PostMapping(value = "/api/basic/sakuras/{id}", produces = MEDIA_TYPE)
    public String editAdminUser(
            @PathVariable("id") Long id,
            @JsonArg("$.key") String key,
            @JsonArg("$.title") String title,
            @JsonArg("$.viewType") String viewType,
            @JsonArg("$.enabled") boolean enabled) {
        Sakura sakura = dao.get(Sakura.class, id);

        if (LOGGER.isDebugEnabled()) {
            debugRequest("[Before:{}]", sakura.toJSON());
        }
        sakura.setKey(key);
        sakura.setTitle(title);
        sakura.setViewType(Sakura.ViewType.valueOf(viewType));
        sakura.setEnabled(enabled);
        if (LOGGER.isDebugEnabled()) {
            debugRequest("[Modify:{}]", sakura.toJSON());
        }
        return objectResult(sakura.toJSON());
    }

}

@@ -235,16 +235,44 @@
 NArray;%0A
+import org.json.JSONObject;%0A
 import o
@@ -326,16 +326,16 @@
 owired;%0A
-
 import o
@@ -685,16 +685,109 @@
 ller %7B%0A%0A
+    public static final String DEFAULT_DISC_COLUMNS = %22id,thisRank,prevRank,totalPt,title%22;%0A%0A
     @Aut
@@ -926,16 +926,29 @@
 tSakura(
+%0A            
 @Request
@@ -953,16 +953,23 @@
 stParam(
+name = 
 %22discCol
@@ -973,16 +973,53 @@
 Columns%22
+, defaultValue = DEFAULT_DISC_COLUMNS
 ) String
@@ -1744,32 +1744,32 @@
 mns);%0A        %7D%0A
-
         return o
@@ -1786,32 +1786,827 @@
 t(data);%0A    %7D%0A%0A
+    @Transactional%0A    @GetMapping(value = %22/api/sakuras/%7Bid%7D%22, produces = MEDIA_TYPE)%0A    public String viewSakura(%0A            @PathVariable(%22id%22) Long id,%0A            @RequestParam(name = %22discColumns%22, defaultValue = DEFAULT_DISC_COLUMNS) String discColumns) %7B%0A        Sakura sakura = dao.get(Sakura.class, id);%0A        if (sakura == null) %7B%0A            return errorMessage(%22%E6%8C%87%E5%AE%9A%E7%9A%84Sakura%E4%B8%8D%E5%AD%98%E5%9C%A8%22);%0A        %7D%0A%0A        JSONObject object = sakura.toJSON();%0A%0A        Set%3CString%3E columns = Arrays.stream(discColumns.split(%22,%22)).collect(Collectors.toSet());%0A        object.put(%22discs%22, buildDiscs(sakura, columns));%0A%0A        if (LOGGER.isDebugEnabled()) %7B%0A            debugRequest(%22%5Bsize=%7B%7D%5D%5BdiscColumns=%7B%7D%5D%22, sakura.getDiscs().size(), discColumns);%0A        %7D%0A        return objectResult(object);%0A    %7D%0A%0A
     @Transaction

Add GET /api/sakuras/:id