package cn.edu.ecnu.stu.bookstore;

import cn.edu.ecnu.stu.bookstore.component.Constants;
import cn.edu.ecnu.stu.bookstore.component.Result;
import cn.edu.ecnu.stu.bookstore.utils.ImageUtil;
import cn.edu.ecnu.stu.bookstore.util.RequestUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.math.BigDecimal;
import java.util.*;

@SpringBootTest
public class BookTest {

    private String token;

    private String storeId;

    private String title;

    private String content;

    private String author;

    private List<String> tags;

    private String bookId;

    @BeforeEach
    public void init() {
        if(token != null)
            return;
        String url = Constants.URL_PREFIX + "/auth/register";
        Map<String, Object> map = new HashMap<>();
        String username = UUID.randomUUID().toString();
        String password = username + "x";
        map.put("username", username);
        map.put("password", password);
        Result result = RequestUtil.post(url, map, null);
        assert result != null && result.getCode() != null && result.getCode().equals(Constants.SUCCESS);

        url = Constants.URL_PREFIX + "/auth/login";
        result = RequestUtil.post(url, map, null);
        assert result != null && result.getCode() != null && result.getCode().equals(Constants.SUCCESS);

        JSONObject data = (JSONObject) result.getData();
        token = data.getString("token");

        url = Constants.URL_PREFIX + "/seller/create_store";
        map = new HashMap<>();
        storeId = "store" + UUID.randomUUID();
        map.put("storeId", storeId);
        result = RequestUtil.post(url, map, token);
        assert result != null && Constants.SUCCESS.equals(result.getCode());

        result = RequestUtil.post(url, map, token);
        assert result != null && Constants.CLIENT_ERROR.equals(result.getCode());

        bookId = "book" + UUID.randomUUID();
        url = Constants.URL_PREFIX + "/seller/add_book";
        title = "title" + UUID.randomUUID();
        author = "author" + UUID.randomUUID();
        String publisher = "publisher" + UUID.randomUUID();
        BigDecimal price = new BigDecimal("29.88");
        String authorIntro = "authorIntro" + UUID.randomUUID();
        String bookIntro = "bookIntro" + UUID.randomUUID();
        content = "content" + UUID.randomUUID();
        tags = Arrays.asList("tag" + UUID.randomUUID(), "tag" + UUID.randomUUID());
        List<String> pictures = Arrays.asList(ImageUtil.convertImageToBase64Str("ff3c65cd-497e-4b17-aa55-5882a38ed2fd.png"));
        map = new HashMap<>();
        map.put("storeId", storeId);
        map.put("bookId", bookId);
        map.put("title", title);
        map.put("author", author);
        map.put("publisher", publisher);
        map.put("price", price);
        map.put("authorIntro", authorIntro);
        map.put("bookIntro", bookIntro);
        map.put("content", content);
        map.put("tags", tags);
        map.put("pictures", pictures);
        result = RequestUtil.post(url, map, token);
        assert result != null && Constants.SUCCESS.equals(result.getCode());
    }

    @Test
    public void testGetBookByTitle() {
        String url = Constants.URL_PREFIX + "/book/title";
        HashMap<String, String> map = new HashMap<>();
        map.put("title", title);
        Result result = RequestUtil.get(url, map, token);
        assert result != null;
        JSONArray data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

        map.put("title", title + "_x");
        result = RequestUtil.get(url, map, token);
        assert result != null;
        data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
    }

    @Test
    public void testGetBookByTitleInStore() {
        String url = Constants.URL_PREFIX + "/book/title_in_store";
        HashMap<String, String> map = new HashMap<>();
        map.put("title", title);
        map.put("storeId", storeId);
        Result result = RequestUtil.get(url, map, token);
        assert result != null;
        JSONArray data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

        map.put("title", title);
        map.put("storeId", storeId + "_x");
        result = RequestUtil.get(url, map, token);
        assert result != null;
        data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
    }

    @Test
    public void testGetBookByAuthor() {
        String url = Constants.URL_PREFIX + "/book/author";
        HashMap<String, String> map = new HashMap<>();
        map.put("author", author);
        Result result = RequestUtil.get(url, map, token);
        assert result != null;
        JSONArray data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

        map.put("author", author + "_x");
        result = RequestUtil.get(url, map, token);
        assert result != null;
        data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
    }

    @Test
    public void testGetBookByAuthorInStore() {
        String url = Constants.URL_PREFIX + "/book/author_in_store";
        HashMap<String, String> map = new HashMap<>();
        map.put("author", author);
        map.put("storeId", storeId);
        Result result = RequestUtil.get(url, map, token);
        assert result != null;
        JSONArray data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

        map.put("author", author);
        map.put("storeId", storeId + "_x");
        result = RequestUtil.get(url, map, token);
        assert result != null;
        data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
    }

    @Test
    public void testGetBookByTag() {
        String url = Constants.URL_PREFIX + "/book/tag";
        HashMap<String, String> map = new HashMap<>();
        for(String tag : tags) {
            map.put("tag", tag);
            Result result = RequestUtil.get(url, map, token);
            assert result != null;
            JSONArray data = (JSONArray) result.getData();
            assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

            map.put("tag", tag + "_x");
            result = RequestUtil.get(url, map, token);
            assert result != null;
            data = (JSONArray) result.getData();
            assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
        }
    }

    @Test
    public void testGetBookByTagInStore() {
        String url = Constants.URL_PREFIX + "/book/tag_in_store";
        HashMap<String, String> map = new HashMap<>();

        for(String tag : tags) {
            map.put("tag", tag);
            map.put("storeId", storeId);
            Result result = RequestUtil.get(url, map, token);
            assert result != null;
            JSONArray data = (JSONArray) result.getData();
            assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

            map.put("storeId", storeId + "_x");
            result = RequestUtil.get(url, map, token);
            assert result != null;
            data = (JSONArray) result.getData();
            assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
        }

    }

    @Test
    public void testGetBookByContent() {
        String url = Constants.URL_PREFIX + "/book/content";
        HashMap<String, String> map = new HashMap<>();
        map.put("content", content);
        Result result = RequestUtil.get(url, map, token);
        assert result != null;
        JSONArray data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;
    }

    @Test
    public void testGetBookByContentInStore() {
        String url = Constants.URL_PREFIX + "/book/content_in_store";
        HashMap<String, String> map = new HashMap<>();
        map.put("content", content);
        map.put("storeId", storeId);
        Result result = RequestUtil.get(url, map, token);
        assert result != null;
        JSONArray data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() > 0;

        map.put("content", content);
        map.put("storeId", storeId + "_x");
        result = RequestUtil.get(url, map, token);
        assert result != null;
        data = (JSONArray) result.getData();
        assert Constants.SUCCESS.equals(result.getCode()) && data.size() == 0;
    }


}
