package cn.forevermc.launcher.service;

import cn.forevermc.launcher.util.Resources;
import com.google.gson.Gson;
import com.imyeyu.fx.task.RunAsync;
import com.imyeyu.fx.utils.BgImage;
import com.imyeyu.inject.annotation.Inject;
import com.imyeyu.inject.annotation.InvokeForInjected;
import com.imyeyu.inject.annotation.Service;
import com.imyeyu.io.IO;
import com.imyeyu.java.TimiJava;
import com.imyeyu.java.bean.CallbackArg;
import com.imyeyu.network.FileRequest;
import com.imyeyu.utils.OS;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.image.Image;
import javafx.scene.layout.Background;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.fluent.Request;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 动态背景地址获取服务
 *
 * @author 夜雨
 * @since 2022-11-28 00:12
 */
@Slf4j
@Service
public class BGService implements OS.FileSystem {

	private static final String CACHE_PATH = "etc" + SEP + "bg";

	@Inject
	private APISettingService apiSettingService;

	@Inject
	private Gson gson;

	private final ObjectProperty<Background> value;
	private final Map<String, File> cacheList = new HashMap<>();

	public BGService() {
		value = new SimpleObjectProperty<>();
		setValue(IO.resourceToInputStream(getClass(), "assets/img/bg.png"));
	}

	@InvokeForInjected
	private void injected() {
		try {
			{
				File[] files = IO.dir(CACHE_PATH).listFiles();
				if (files != null) {
					for (int i = 0; i < files.length; i++) {
						cacheList.put(files[i].getName(), files[i]);
					}
				}
			}
			if (TimiJava.isNotEmpty(cacheList)) {
				List<File> files = new ArrayList<>(cacheList.values());
				Collections.shuffle(files);
				setValue(IO.getInputStream(files.get(0)));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 从缓存随机抽取
		apiSettingService.valueProperty().addListener((obs, o, setting) -> {
			if (setting == null) {
				return;
			}
			try {
				String active = setting.getBg().getActive();
				if (TimiJava.isNotEmpty(active)) {
					if (cacheList.containsKey(active)) {
						setValue(IO.getInputStream(cacheList.get(active)));
					} else {
						fetch(active, active, this::setValue);
					}
				} else {
					List<String> list = setting.getBg().getList();
					if (TimiJava.isNotEmpty(list)){
						Collections.shuffle(list);
						String shuffleMongoId = list.get(0);
						if (cacheList.containsKey(shuffleMongoId)) {
							setValue(IO.getInputStream(cacheList.get(shuffleMongoId)));
						} else {
							fetch(shuffleMongoId, shuffleMongoId, this::setValue);
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
	}

	private void setValue(InputStream stream) {
		value.set(new BgImage(new Image(stream, -1, -1, false, false)).cover().build());
	}

	private void fetch(String mongoId, String fileName, CallbackArg<InputStream> callback) {
		new RunAsync<InputStream>() {

			@Override
			protected InputStream call() throws Exception {
				File file = IO.file(CACHE_PATH + SEP + fileName);
				FileRequest.get(Resources.TIMI_SERVER_API + "/attachment/read/" + mongoId).toFile(file);
				cacheList.put(mongoId, file);
				return IO.getInputStream(file);
			}

			@Override
			protected void onFinish(InputStream stream) {
				callback.handler(stream);
			}
		}.start();
	}

	public ReadOnlyObjectProperty<Background> valueProperty() {
		return value;
	}

	public Background getValue() {
		return value.get();
	}
}
