package com.kospo.talk.config.utils;

import com.kospo.talk.payload.ListeningDto;
import com.kospo.talk.payload.MasterDto;
import org.springframework.data.domain.Sort;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class CommonUtils {
    private static HashMap<String, Set<HashMap<String, Integer>>> listenings;

    public CommonUtils() {

    }

    public static void setListening(ListeningDto listeningDto) {
        if(listenings == null) listenings = new HashMap<>();
        Set<HashMap<String, Integer>> getList = listenings.get(listeningDto.getSabun());
        HashMap<String, Integer> map = new HashMap<>();
        if(getList == null) {
            getList = new HashSet<>();
            map.put(listeningDto.getTalkId(), listeningDto.getStatus());
        } else {

            getList = getList.stream().filter((li) -> !li.containsKey(listeningDto.getTalkId())).collect(Collectors.toSet());

            map.put(listeningDto.getTalkId(), listeningDto.getStatus());
        }



        getList.add(map);
        listenings.put(listeningDto.getSabun(), getList);
    }

    public static Integer getListening(ListeningDto listeningDto) {
        AtomicInteger result = new AtomicInteger();
        if(listenings == null) {
            listenings = new HashMap<>();
            return 0;
        } else {
            Set<HashMap<String, Integer>> getList = listenings.get(listeningDto.getSabun());
            if(getList == null) {
                return 0;
            } else {
                getList.stream().forEach((li) -> {
                    if (li.containsKey(listeningDto.getTalkId())) {
                        result.set(li.get(listeningDto.getTalkId()));
                    }
                });
                return result.get();
            }

        }

    }

    public static Sort convertSort(String field) {
        String[] propertyAndDirection = field.split(",");
        if(propertyAndDirection.length == 1) propertyAndDirection = field.split(" ");
        String property = propertyAndDirection[0];
        Sort.Direction direction = Sort.DEFAULT_DIRECTION;
        if(propertyAndDirection.length > 1) {
            String directionString = propertyAndDirection[1];
            direction = Sort.Direction.fromOptionalString(directionString)
                    .orElse(Sort.DEFAULT_DIRECTION);
        }
        Sort.Order order = new Sort.Order(direction, property);
        return Sort.by(order);
    }


    public static String dateFormat(Date setDate, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(setDate);
    }


    public static String dateFormat(String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(new Date());
    }

    public static Date stringToDate(String dateString) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
//        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));

        Date date = null;
        try {
            date = sdf.parse(dateString);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        return date;
    }

    public static LocalDateTime stringToDate(String dateString, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
//        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Seoul"));

        LocalDateTime date = null;
        date = LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(pattern));
        return date;
    }

    public static String generateFileName() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSSSSSS");
        String datePart = now.format(formatter);
        String uniquePart = UUID.randomUUID().toString().substring(0, 8);
        return datePart + "_" + uniquePart;
    }

    public static boolean checkAllowExt(String fileNm) {
        String fileExtNm = "";
        List<String> allowList = Arrays.asList(
                "7z", "ai", "art", "asd", "avi", "bak", "bin", "c", "cell", "cfg", "cls", "css", "csv", "der", "drt", "dsd", "dwg", "dxf", "emf", "eps", "gz", "html", "hwpx", "inf", "info", "ini", "java", "is", "key", "lic", "log", "m", "mov", "mp3", "mp4", "mpeg", "msg", "ods", "odt", "otf", "p12", "pdf", "png", "ppsx", "pptm", "pptx", "psd", "svg", "tar", "tgz", "tif", "tiff", "tmp", "ttf", "twb", "twbx", "ui", "url", "vsd", "wav", "webp", "whl", "wmf", "wmv", "woff", "xl", "xla", "xlm", "xlsb", "xlsm", "xml", "xsd", "bmp", "doc", "docx", "eml", "gif", "hwp", "jpe", "jpeg", "jpg", "pfx", "ppt", "txt", "xls", "xlsx", "zip"
        );

        fileExtNm = fileNm.toLowerCase().substring(fileNm.toLowerCase().lastIndexOf(".") + 1);
        fileExtNm = fileExtNm.toLowerCase();

        String allows = allowList.stream().map((str) -> str).collect(Collectors.joining(","));

        return allows.contains(fileExtNm);
    }

    public static synchronized void uploadAndResume(String path, String vnm, byte[] data) {
        File file = new File(path, vnm);
        BufferedOutputStream bos = null;

        try {
            if (file.exists()) {
                bos = new BufferedOutputStream(new FileOutputStream(file, true));

            } else {
                bos = new BufferedOutputStream(new FileOutputStream(file));

            }
            bos.write(data);
            bos.flush();
            bos.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    }
}