package itn.let.kakao.kakaoComm.kakaoApi;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import egovframework.rte.fdl.property.EgovPropertyService;
import itn.com.cmm.service.EgovFileMngUtil;
import itn.com.cmm.service.FileVO;
import itn.let.kakao.kakaoComm.KakaoReturnVO;
import itn.let.kakao.kakaoComm.KakaoVO;
import itn.let.utl.fcc.service.EgovStringUtil;

@Component("kakaoApiImageUpload")
public class KakaoApiImageUpload {

	/** 비즈 URL */
	@Value("#{globalSettings['Globals.mjon.biz.url']}")
	private String mjonBizUrl;
	
	/** 비즈 회원 아이디 */
	@Value("#{globalSettings['Globals.mjon.biz.id']}")
	private String mjonBizId;
	
	/** 비즈 회원 API 키*/
	@Value("#{globalSettings['Globals.mjon.biz.kakao.apiKey']}")
	private String mjonBizKakaoApiKey;
	
    @Resource(name = "propertiesService")
    protected EgovPropertyService propertyService;
	
	
	/**
	* @Method Name : kakaoApiImageUpload
	* @작성일 : 2023. 1. 19.
	* @작성자 :  우영두
	* @Method 설명 : 친구톡 이미지 등록
	*/
	public Map<String, String> kakaoApiImageUpload(KakaoVO kakaoVO, Map<String, MultipartFile> files, int fileKeyParam) throws Exception {
		
		Map<String, String> resultMap = new HashMap<String, String>();
		
		try {
			
			int fileKey = fileKeyParam;
			String storePathString = propertyService.getString("Globals.fileStorePath");
			
			File saveFolder = new File(storePathString);

			if (!saveFolder.exists() || saveFolder.isFile()) {
			    saveFolder.mkdirs();
			}
			
			List<MultipartFile> tmp = new ArrayList<MultipartFile>(files.values());
			ListIterator<MultipartFile> itr = tmp.listIterator(tmp.size());
			
			MultipartFile file;
			String filePath = "";
			FileVO fvo;
			File imgFile = null;
			String newName = "";
			String fileExt = "";
			while (itr.hasPrevious()) {
				
				file = itr.previous();
			    
			    String orginFileName = file.getOriginalFilename();

			    //--------------------------------------
			    // 원 파일명이 없는 경우 처리
			    // (첨부가 되지 않은 input file type)
			    //--------------------------------------
			    if ("".equals(orginFileName)) {
			    	continue;
			    }
			    ////------------------------------------

			    int index = orginFileName.lastIndexOf(".");
			    fileExt = orginFileName.substring(index + 1);
			    newName = EgovStringUtil.getTimeStamp() + fileKey;
			    long _size = file.getSize();

			    //이미지 파일 처리라서 확장자까지 모두 붙여서 파일 생성 함
			    if (!"".equals(orginFileName)) {
					filePath = saveFolder + File.separator + newName + "." + fileExt;
					file.transferTo(new File(filePath));
					
					File newFile = new File(filePath);
				    InputStream inputStream = new FileInputStream(newFile);
			        Image img = new ImageIcon(newFile.toString()).getImage(); // 파일 정보 추출
			        
				    int orgWidth = img.getWidth(null);
				    int orgHeight = img.getHeight(null);
				    
				    long bytes = file.getSize();
			        long kilobyte = bytes / 1024;
			        long megabyte = kilobyte / 1024;
				    
			        //일반이미지, 와이드 이미지 타입별 용량, 크기 체크
				    String imgType = kakaoVO.getImageType();
				   
				    /*
				     * 	
						!기본 이미지
						파일규격 : JPG, JPEG, PNG 만 가능/ 용량 최대 500KB
						권장 사이즈 : 720px X 720px(가로 500px 미만, 가로:세로 비율이 2:1 미만 또는 3:4 초과 시 업로드 불가)
						!와이드 이미지
						파일규격 : JPG, JPEG, PNG 만 가능/ 용량 최대 2MB 사이즈 : 800px X 600px
				     *
				     * */
				    if(imgType.equals("W")) {
				    	
				    	if(orgWidth != 800 && orgHeight != 600) {//와이드 이미지인 경우 800 X 600 사이즈만 등록 가능함.
				    		
				    		resultMap.put("code", "405");
				    		resultMap.put("msg", "와이드 이미지 크기는 800px X 600px 이어야 합니다.");
				    		
				    		return resultMap;
				    	}else if(megabyte > 2) {//와이드 이미지 최대 용량은 2MB 
				    		
				    		resultMap.put("code", "405");
				    		resultMap.put("msg", "와이드 이미지 용량은 2MB 이내여야 합니다.");
				    		
				    		return resultMap;
				    	}
				    	
				    }else {//일반 이미지 처리
				    	
				    	//일반 이미지 최대 크기는 500KB를 넘을 수 없다. 실제 498KB여도 500이 넘었다고 등록이 안됨. ㅋ
				    	if(kilobyte > 497) {
					    	
					    	resultMap.put("code", "405");
				    		resultMap.put("msg", "파일 최대 용량은 초과하였습니다. 이미지 최대 용량은 500KB를 초과할 수 없습니다.");
				    		
				    		return resultMap;
					    	
					    }else if(orgWidth < 500) {//가로 사이즈가 500px 미만이면 안됨
					    	
					    	resultMap.put("code", "405");
				    		resultMap.put("msg", "일반 이미지의 최소 가로 사이즈는 500px 이상이어야 합니다.");
				    		
				    		return resultMap;
					    	
					    }
				    	
				    	//일반 이미지 권장사이즈 초과시 리사이즈 처리 후 저장
						int MAX_WIDTH = 720;
						int MAX_HEIGHT = 720;
					    
						if(orgWidth > 720 || orgHeight > 720) {
					    	
					        if (orgWidth > MAX_WIDTH) {
					        	orgHeight = (int) (orgHeight * (MAX_WIDTH / (float) orgWidth));
					        	orgWidth = MAX_WIDTH;
					        }

					        if (orgHeight > MAX_HEIGHT) {
					        	orgWidth = (int) (orgWidth * (MAX_HEIGHT / (float) orgHeight));
					        	orgHeight = MAX_HEIGHT;
					        }
					        
					        //이미지 리사이징 요청
					        EgovFileMngUtil fileMngUtil = new EgovFileMngUtil();
					        BufferedImage resizedImage = fileMngUtil.resize(inputStream ,orgWidth , orgHeight );
					        
					        //리사이징된 파일 덮어쓰기
					        ImageIO.write(resizedImage, "jpg", new File(filePath));
					        
					    }
				    	
				    }
				    
					imgFile = new File(filePath);
					
			    }
			    
			}
			
			if(imgFile.exists()) {//파일이 존재하면 카카오로 전송 처리
				
				//첨부파일 등록 API 전송 요청
				
				String apiUrl = "/v3/kakao/image/upload";
				String sendUrl = mjonBizUrl+ apiUrl;
				
				String fullFileName = newName + "." + fileExt;
				CloseableHttpClient httpClient = HttpClients.createDefault();
				HttpPost httpPost = new HttpPost(sendUrl);
				HttpEntity httpEntity = MultipartEntityBuilder.create()
						.addTextBody("bizId", mjonBizId)
						.addTextBody("apiKey", mjonBizKakaoApiKey)
						.addTextBody("imageType", kakaoVO.getImageType())
						.addTextBody("title", kakaoVO.getImgTitle())
						.addTextBody("link", kakaoVO.getImgLink())
						.addTextBody("senderKey", kakaoVO.getSenderKey())
						.addBinaryBody("image", new File(filePath),ContentType.MULTIPART_FORM_DATA,fullFileName)
						.build();
				
				httpPost.setEntity(httpEntity);

		        CloseableHttpResponse response = httpClient.execute(httpPost);

				String result = "";
				
				String statusCode = Integer.toString(response.getStatusLine().getStatusCode());
				
				if(statusCode.equals("200")) {
					result = EntityUtils.toString(response.getEntity()); 
					
					result = new String(result.getBytes("iso-8859-1"));//한글 깨짐 현상이 있어서 변환 해줌.
					JSONParser parser = new JSONParser();
					Object obj = parser.parse(result);
					JSONObject object = (JSONObject) obj;
					
					String code = object.get("code").toString();
					String msg = object.get("message").toString();
					String imgUrl = "";
					
					if(code.equals("200")) {
						imgUrl = object.get("image").toString();
					}
					
					resultMap.put("code", code);
					resultMap.put("msg", msg);
					resultMap.put("imgUrl", imgUrl);
					
				}else {
					
					System.out.println("오류 발생");
				}
		        
		        httpClient.close();
				
			}
			
		}catch (Exception e) {
			System.out.println("kakaoApiImageUpload API Error !!! " + e);
			resultMap.put("code", "400");
			resultMap.put("msg", "친구톡 이미지 등록에 오류가 발생하였습니다.");
			resultMap.put("imgUrl", "");
			return resultMap;
		}
		return resultMap;
	}
	
	
	/**
	* @Method Name : kakaoApiTemplateImageUpload
	* @작성일 : 2023. 2. 16.
	* @작성자 :  우영두
	* @Method 설명 : 알림톡 이미지 업로드 요청
	*/
	public Map<String, String> kakaoApiTemplateImageUpload(KakaoVO kakaoVO, Map<String, MultipartFile> files, int fileKeyParam) throws Exception {
		
		Map<String, String> resultMap = new HashMap<String, String>();
		
		try {
			
			int fileKey = fileKeyParam;
			String storePathString = propertyService.getString("Globals.fileStorePath");
			
			File saveFolder = new File(storePathString);

			if (!saveFolder.exists() || saveFolder.isFile()) {
			    saveFolder.mkdirs();
			}
			
			List<MultipartFile> tmp = new ArrayList<MultipartFile>(files.values());
			ListIterator<MultipartFile> itr = tmp.listIterator(tmp.size());
			
			MultipartFile file;
			String filePath = "";
			FileVO fvo;
			File imgFile = null;
			String newName = "";
			String fileExt = "";
			while (itr.hasPrevious()) {
				
				file = itr.previous();
			    
			    String orginFileName = file.getOriginalFilename();

			    //--------------------------------------
			    // 원 파일명이 없는 경우 처리
			    // (첨부가 되지 않은 input file type)
			    //--------------------------------------
			    if ("".equals(orginFileName)) {
			    	continue;
			    }
			    ////------------------------------------

			    int index = orginFileName.lastIndexOf(".");
			    fileExt = orginFileName.substring(index + 1);
			    newName = EgovStringUtil.getTimeStamp() + fileKey;
			    long _size = file.getSize();

			    //이미지 파일 처리라서 확장자까지 모두 붙여서 파일 생성 함
			    if (!"".equals(orginFileName)) {
					filePath = saveFolder + File.separator + newName + "." + fileExt;
					file.transferTo(new File(filePath));
					
					File newFile = new File(filePath);
				    InputStream inputStream = new FileInputStream(newFile);
			        Image img = new ImageIcon(newFile.toString()).getImage(); // 파일 정보 추출
			        
				    int orgWidth = img.getWidth(null);
				    int orgHeight = img.getHeight(null);
				    
				    long bytes = file.getSize();
			        long kilobyte = bytes / 1024;
			        long megabyte = kilobyte / 1024;
				    
			        //일반이미지, 와이드 이미지 타입별 용량, 크기 체크
				    String imgType = kakaoVO.getImageType();
				   
				    /*
				     * 	
						!기본 이미지
						파일규격 : JPG, JPEG, PNG 만 가능/ 용량 최대 500KB
						권장 사이즈 : 720px X 720px(가로 500px 미만, 가로:세로 비율이 2:1 미만 또는 3:4 초과 시 업로드 불가)
						!와이드 이미지
						파일규격 : JPG, JPEG, PNG 만 가능/ 용량 최대 2MB 사이즈 : 800px X 600px
				     *
				     * */
				    
				    //이미지 최대 크기는 500KB를 넘을 수 없다. 실제 498KB여도 500이 넘었다고 등록이 안됨. ㅋ
			    	if(kilobyte > 497) {
				    	
				    	resultMap.put("code", "405");
			    		resultMap.put("msg", "파일 최대 용량은 초과하였습니다. 이미지 최대 용량은 500KB를 초과할 수 없습니다.");
			    		
			    		return resultMap;
				    	
				    }else if(orgWidth < 500) {//가로 사이즈가 500px 미만이면 안됨
				    	
				    	resultMap.put("code", "405");
			    		resultMap.put("msg", "이미지의 최소 가로 사이즈는 500px 이상이어야 합니다.");
			    		
			    		return resultMap;
				    	
				    }
			    	
			    	//일반 이미지 권장사이즈 초과시 리사이즈 처리 후 저장
					int MAX_WIDTH = 800;
					int MAX_HEIGHT = 400;
				    
					//800 * 400 이 넘으면 리사이징 처리
					/*if(orgWidth > 800 || orgHeight > 400) {
				    	
						orgWidth = MAX_WIDTH;
						orgHeight = MAX_HEIGHT;
						
				        if (orgWidth > MAX_WIDTH) {
				        	orgHeight = (int) (orgHeight * (MAX_WIDTH / (float) orgWidth));
				        	orgWidth = MAX_WIDTH;
				        }

				        if (orgHeight > MAX_HEIGHT) {
				        	orgWidth = (int) (orgWidth * (MAX_HEIGHT / (float) orgHeight));
				        	orgHeight = MAX_HEIGHT;
				        }
				        
				        //이미지 리사이징 요청
				        EgovFileMngUtil fileMngUtil = new EgovFileMngUtil();
				        BufferedImage resizedImage = fileMngUtil.resize(inputStream ,orgWidth , orgHeight );
				        
				        //리사이징된 파일 덮어쓰기
				        ImageIO.write(resizedImage, "jpg", new File(filePath));
				        
				    }*/
				    
					imgFile = new File(filePath);
					
			    }
			    
			}
			
			if(imgFile.exists()) {//파일이 존재하면 카카오로 전송 처리
				
				//첨부파일 등록 API 전송 요청
				
				String apiUrl = "/v3/kakao/image/alimtalk/template";
				String sendUrl = mjonBizUrl+ apiUrl;
				
				String fullFileName = newName + "." + fileExt;
				CloseableHttpClient httpClient = HttpClients.createDefault();
				HttpPost httpPost = new HttpPost(sendUrl);
				HttpEntity httpEntity = MultipartEntityBuilder.create()
						.addTextBody("bizId", mjonBizId)
						.addTextBody("apiKey", mjonBizKakaoApiKey)
						.addBinaryBody("image", new File(filePath),ContentType.MULTIPART_FORM_DATA,fullFileName)
						.build();
				
				httpPost.setEntity(httpEntity);

		        CloseableHttpResponse response = httpClient.execute(httpPost);

				String result = "";
				
				String statusCode = Integer.toString(response.getStatusLine().getStatusCode());
				
				if(statusCode.equals("200")) {
					result = EntityUtils.toString(response.getEntity()); 
					
					result = new String(result.getBytes("iso-8859-1"));//한글 깨짐 현상이 있어서 변환 해줌.
					JSONParser parser = new JSONParser();
					Object obj = parser.parse(result);
					JSONObject object = (JSONObject) obj;
					
					String code = object.get("code").toString();
					String msg = object.get("message").toString();
					String imgUrl = "";
					
					if(code.equals("200")) {
						imgUrl = object.get("image").toString();
					}
					
					resultMap.put("code", code);
					resultMap.put("msg", msg);
					resultMap.put("imgUrl", imgUrl);
					
				}else {
					
					System.out.println("오류 발생");
				}
		        
		        httpClient.close();
				
			}
			
		}catch (Exception e) {
			System.out.println("kakaoApiTemplateImageUpload API Error !!! " + e);
			resultMap.put("code", "400");
			resultMap.put("msg", "알림톡 이미지 등록에 오류가 발생하였습니다.");
			resultMap.put("imgUrl", "");
			return resultMap;
		}
		return resultMap;
	}
	
	
	/**
	* @throws Exception 
	 * @Method Name : kakaoApiImageDelete
	* @작성일 : 2023. 3. 23.
	* @작성자 :  우영두
	* @Method 설명 : 카카오 친구톡 이미지 삭제 요청
	*/
	@SuppressWarnings("unchecked")
	public KakaoReturnVO kakaoApiImageDelete(KakaoVO kakaoVO) throws Exception {
		KakaoReturnVO kakaoReturnVO = new KakaoReturnVO();
		try {
			
			String apiUrl = "/v3/kakao/image/delete";
			String sendUrl = mjonBizUrl + apiUrl;
			 
			JSONObject jsonObject = new JSONObject(); 
			jsonObject.put("bizId", mjonBizId);
			jsonObject.put("apiKey", mjonBizKakaoApiKey);
			jsonObject.put("imageUrl", kakaoVO.getTemplateImageUrl());
			
			HttpClient httpClient = HttpClientBuilder.create().build(); 
			HttpPost httpPost = new HttpPost(sendUrl); 
			httpPost.setEntity(new StringEntity(jsonObject.toString(), "UTF-8")); 
			httpPost.addHeader("Content-type", "application/json"); 
			httpPost.addHeader("Accept", "application/json");
			
			HttpResponse response = httpClient.execute(httpPost);

			String result = "";
			String statusCode = Integer.toString(response.getStatusLine().getStatusCode());
			
			if(statusCode.equals("200")) {
				
				result = EntityUtils.toString(response.getEntity()); 
				
				result = new String(result.getBytes("iso-8859-1"));//한글 깨짐 현상이 있어서 변환 해줌.
				System.out.println(result);
				JSONParser parser = new JSONParser();
				Object obj = parser.parse(result);
				JSONObject object = (JSONObject) obj;
				
				String code = object.get("code").toString();
				String msg = object.get("message").toString();
				
				kakaoReturnVO.setBizReturnCode(code);
				kakaoReturnVO.setBizReturnMsg(msg);
			}else {
				kakaoReturnVO.setBizReturnMsg("400 : 명령을 실행 오류");
			}
			
		} catch (Exception e) {
			
			System.out.println("kakaoApiImageDelete API Error !!! " + e);
			kakaoReturnVO.setBizReturnCode("400");
			kakaoReturnVO.setBizReturnMsg("친구톡 이미지 삭제에 오류가 발생하였습니다.");
			return kakaoReturnVO;
		}
		
		return kakaoReturnVO;
	}
	
}
