package com.github.novicezk.midjourney.service.store;

import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.stream.StreamUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.novicezk.midjourney.service.TaskStoreService;
import com.github.novicezk.midjourney.support.Task;
import com.github.novicezk.midjourney.support.TaskCondition;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class InMemoryTaskStoreServiceImpl implements TaskStoreService {
	private final TimedCache<String, Task> taskMap;

	public InMemoryTaskStoreServiceImpl(Duration timeout) {
		this.taskMap = CacheUtil.newTimedCache(timeout.toMillis());
	}

	@Override
	public void save(Task task) {
		this.taskMap.put(task.getId(), task);
	}

	@Override
	public void delete(String key) {
		this.taskMap.remove(key);
	}

	@Override
	public Task get(String key) {
        Task task = this.taskMap.get(key);
        if(ObjectUtil.isNotNull(task)) {
            try {
                task.setFinishDate(DateUtil.formatDateTime(new Date(task.getFinishTime())));
                task.setSubmitDate(DateUtil.formatDateTime(new Date(task.getSubmitTime())));
                task.setStartDate(DateUtil.formatDateTime(new Date(task.getStartTime())));
                Long costTime = (task.getFinishTime() - task.getStartTime()) / 1000;
                task.setCostTime(costTime);
            } catch (Exception e) {
            }
        }
        return this.taskMap.get(key);
	}

	@Override
	public List<Task> list() {
        List<Task> tasks = ListUtil.toList(this.taskMap.iterator());
        tasks.stream().forEach(x -> {
            try {
                x.setFinishDate(DateUtil.formatDateTime(new Date(x.getFinishTime())));
                x.setSubmitDate(DateUtil.formatDateTime(new Date(x.getSubmitTime())));
                x.setStartDate(DateUtil.formatDateTime(new Date(x.getStartTime())));
                Long costTime = (x.getFinishTime() - x.getStartTime()) / 1000;
                x.setCostTime(costTime);
            } catch (Exception e) {
            }
        });
        return ListUtil.toList(this.taskMap.iterator());
	}

	@Override
	public List<Task> list(TaskCondition condition) {
		return StreamUtil.of(this.taskMap.iterator()).filter(condition).toList();
	}

	@Override
	public Task findOne(TaskCondition condition) {
		return StreamUtil.of(this.taskMap.iterator()).filter(condition).findFirst().orElse(null);
	}

}
