package com.icomsys.main_vm.biz.rcp.oprManage.service.impl;

import com.icomsys.main_vm.biz.rcp.oprManage.service.OprManageBgmService;
import com.icomsys.main_vm.biz.rcp.oprManage.vo.OprManageBgmVO;
import com.icomsys.main_vm.db.mybatis.mapper.BgmManageMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;

import java.io.*;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
@Slf4j
@RequiredArgsConstructor
public class OprManageBgmServiceImpl implements OprManageBgmService {

    @Value("${file.path}")
    private String filePath;

    @Value("${feign.url.bgmpath}")
    private String bgmPath;

    @Value("${feign.url.s3Bucket}")
    private String s3Bucket;


    @Autowired
    private BgmManageMapper bgmManageMapper;

    @Override
    public int insertBgm(OprManageBgmVO vo) {
        return bgmManageMapper.insertBgm(vo);

    }

    public List<String> uploadBgm(List<MultipartFile> multipartFile) {
        List<String> fileNameList = new ArrayList<>();

        //s3클라이언트 인스턴스 생성
        S3Client s3 = S3Client.builder()
                .region(Region.AP_NORTHEAST_2)
                .credentialsProvider(InstanceProfileCredentialsProvider.builder().build())
                .build();

        multipartFile.forEach(file ->
        {
            String fileName = file.getOriginalFilename();
            log.info("fileName : " + fileName);

            try (InputStream inputStream = file.getInputStream()) {

                //PutObjectRequest 생성
                PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                        .bucket(s3Bucket)
                        .key(bgmPath + fileName)
                        //.acl(ObjectCannedACL.PUBLIC_READ)
                        .contentType(file.getContentType())
                        .contentLength(file.getSize())
                        .build();
                fileNameList.add(fileName);
                PutObjectResponse response = s3.putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));

            } catch (Exception e) {
                e.printStackTrace();
//                throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "업로드에 실패했습니다.");
            }
            //fileNameList.add(awsImgUrl+fileName);
            //fileNameList.add(s3Bucket + "/filepath");
        });

        return fileNameList;
    }

    /*

    @Override
    public List<OprManageBgmListVo> selectBgmList(OprManageBgmListVo vo) {
        List<OprManageBgmListVo> oprManageBgmList = bgmManageMapper.selectBgmList(vo);
        return oprManageBgmList;
    }

     */



    /*
    @Override
    public List<HashMap> selectBgmList(OprManageBgmListVo vo) {
        return bgmManageMapper.selectBgmList(vo);
    }
    */

/*
    @Override
    public void checkRecordFileFromS3(List<HashMap> list) {
        if ("local".equals(s3Bucket)) {
            for (HashMap fMap : list) { // 대화 내용 리스트
                if (fMap.containsKey("bgmFilePath")) {
                    fMap.put("bgmFilePath", "");
                }
            }
            return;
        }

        String bucketName = s3Bucket; // 버킷명

        // 1. s3 client 생성
        S3Client s3 = S3Client.builder()
                .region(Region.AP_NORTHEAST_2)
                .credentialsProvider(InstanceProfileCredentialsProvider.create())
                .build();
        log.debug("s3Client create");

        // 2. 버킷 내에 각 파일 확인
        for (HashMap fMap : list) { // 대화 내용 리스트
            if (fMap.containsKey("bgmFilePath")) {
                String recFilePath = fMap.get("bgmFilePath").toString();

                boolean isS3Object = false;
                if (!"".equals(recFilePath)) {
                    recFilePath = recFilePath.substring(1);
                    List<S3Object> sList = listBucketObjects(s3,bucketName,recFilePath); // 버킷에 파일 찾기

                    for (S3Object myValue : sList) {
                        if (myValue.key().equals(recFilePath)) {
                            isS3Object = true;
                            log.info("name of the key " + myValue.key() + " exist");
                        }
                    }

                    if (!isS3Object) {
                        recFilePath = "";
                    }
                }
                fMap.put("recFilePath",recFilePath);
            }
        }
    }*/

    @Override
    public String playRecordFileFromS3(String path) {
        String bucketName = s3Bucket; // 버킷명

        // 1. s3 client 생성
        S3Client s3 = S3Client.builder()
                .region(Region.AP_NORTHEAST_2)
                .credentialsProvider(InstanceProfileCredentialsProvider.create())
                .build();

        // 2. 다운로드 된 파일인지 확인
        String fullPath = filePath + "bgmfile/" + recordDownloadFileName(path);
        log.info("fullPath : " + fullPath);
        File file = new File(fullPath);
        if (file.exists()) {
            if (!file.isDirectory()) {
                return recordServerFilePath(recordDownloadFileName(path));
            }
        }

        // 3. 다운로드 되지 않은 경우 다운로드 진행
        return recordServerFilePath(downloadFileFromS3(path, s3, bucketName));

    }

    private List<S3Object> listBucketObjects(S3Client s3, String bucketName, String path) {

        ListObjectsRequest listObjects = ListObjectsRequest
                .builder()
                .prefix(path)
                .bucket(bucketName)
                .build();

        ListObjectsResponse res = s3.listObjects(listObjects);

        return res.contents();
    }

    private String downloadFileFromS3(String keyName, S3Client s3, String bucketName) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar c1 = Calendar.getInstance();

        String fileFormat = filePath + "bgmfile/";
        //String fileName = recordDownloadFileName(keyName);
        String fileName;
        try {

            log.debug("Downloading " + keyName + " from " + bucketName + "S3 bucket ...");

            int beginIndex = keyName.lastIndexOf("%2F")+3;
            int endIndex = keyName.length();
            String result = keyName.substring(beginIndex, endIndex);
            String keyName2 = URLDecoder.decode(bgmPath + result, "UTF-8");
            fileName = result;
            log.info("keyname : " + keyName);
            log.info("keyname2 : " + keyName2);
            GetObjectRequest objectRequest = GetObjectRequest
                    .builder()
                    .key(keyName2)
                    .bucket(bucketName)
                    .build();
            log.info("key fin");
            ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest);
            byte[] data = objectBytes.asByteArray();

            File Folder = new File(fileFormat + sdf.format(c1.getTime()));
            if (!Folder.exists()) {
                try {
                    Folder.mkdirs();
                } catch (Exception e) {
                    log.debug("error_mkdir");
                    e.getStackTrace();
                }
            }

            File myFile = new File(fileFormat + fileName);
            OutputStream os = new FileOutputStream(myFile);

            os.write(data);
            log.debug("Successfully obtained " + keyName + " from an S3 object");
            os.close();

        } catch (IOException ex) {
            fileName = "";
            log.error(ex.getMessage());
        } catch (S3Exception e) {
            fileName = "";
            log.error(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return fileName;
    }

    private String recordDownloadFileName(String keyName) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar c1 = Calendar.getInstance();
        String fileName = sdf.format(c1.getTime()) + "/";

        String filePattern = "bgmfile/[0-9]{8}/";
        Pattern pattern = Pattern.compile(filePattern);
        Matcher match = pattern.matcher(keyName);

        if (match.find()) {
            log.debug("bgm file Name :" + keyName.replaceAll(filePattern,"").trim());
            fileName = fileName + keyName.replaceAll(filePattern,"").trim();
        }

        return fileName;
    }

    private String recordServerFilePath(String keyName) {

        InetAddress local;
        String ip = "";
        try {
            local = InetAddress.getLocalHost();
            ip = local.getHostAddress();
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        }

        return "http://" + ip + ":8050/files/bgmfile/" + keyName;
    }

}
