package com.example.demo.service.impl;

import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.common.APIResponse;
import com.example.demo.dto.AdunitEndpointCreateDTO;
import com.example.demo.dto.AdunitEndpointListDTO;
import com.example.demo.dto.EndpointResponseDTO;
import com.example.demo.entity.AdunitEndpoint;
import com.example.demo.entity.Configurations;
import com.example.demo.entity.Dsp;
import com.example.demo.entity.EndPoint;
import com.example.demo.repository.AdunitEndpointRepository;
import com.example.demo.repository.ConfigurationRepo;
import com.example.demo.repository.DspRepository;
import com.example.demo.repository.EndpointRepository;
import com.example.demo.service.AdunitEndpointService;

import redis.clients.jedis.Jedis;

@Service
public class AdunitEndpointServiceImpl implements AdunitEndpointService{

	@Autowired
	private AdunitEndpointRepository repo;
	
	@Autowired
	private Jedis jedis;

	@Autowired
	private EndpointRepository endrepo;
	
	@Autowired
	private DspRepository dsprepo;
	
	@Autowired
	private ConfigurationRepo configrepo;

	
	@Override
	public APIResponse createlinking(AdunitEndpointCreateDTO create) {
		APIResponse api = new APIResponse();
		
		AdunitEndpoint aduend = new AdunitEndpoint();
		aduend.setAdunit_id(create.getAdunit_id());
		aduend.setEndpoint_id(create.getEndpoint_id());
		repo.save(aduend);
		
		String key ="Adunit_Endpoint_"+aduend.getAdunit_id();
		List<AdunitEndpoint> adu = repo.findbyadunit(create.getAdunit_id());
		List<UUID> adunit_id = adu.stream().map(id->id.getEndpoint_id()).collect(Collectors.toList());
		JSONArray ja = new JSONArray();
		for (UUID id : adunit_id) {
			JSONObject obj = new JSONObject();
			obj.put("endpoint_id", id.toString());
			ja.add(obj);
		}
		Map<String, String> map = new HashMap<>();
		map.put("connectedEndpoint", ja.toString());
		jedis.hmset(key, map);
		
		api.setData(aduend);
		api.setMessage("Adunit_Endpoint_Linked_Successfully");
		api.setMsgCode("ADUNIT_ENDPOINT_LINKED_SUCCESSFULLY");
		return api;
	}

	@Override
	public APIResponse deletelinking(AdunitEndpointCreateDTO update) {
		APIResponse api = new APIResponse();
		
		AdunitEndpoint aduend = repo.findbyadunitandEndpoint(update.getAdunit_id(), update.getEndpoint_id());
		repo.delete(aduend);
		
		String key ="Adunit_Endpoint"+aduend.getAdunit_id();
		jedis.del(key);
		List<AdunitEndpoint> adu = repo.findbyadunit(update.getAdunit_id());
		List<UUID> adunit_id = adu.stream().map(id->id.getEndpoint_id()).collect(Collectors.toList());
		JSONArray ja = new JSONArray();
		for (UUID id : adunit_id) {
			JSONObject obj = new JSONObject();
			obj.put("endpoint_id", id.toString());
			ja.add(obj);
		}
		Map<String, String> map = new HashMap<>();
		map.put("connectedEndpoint", ja.toString());
		jedis.hmset(key, map);
		
		api.setData(update);
        api.setMessage("Adunit_Endpoint_Unlinked_Successfully");
        api.setMsgCode("ADUNIT_ENDPOINT_UNLINKED_SUCCESSFULLY");
		return api;
	}

	@Override
	public APIResponse list(AdunitEndpointListDTO list) {
		APIResponse api = new APIResponse();
		
		List<AdunitEndpoint> aduend = repo.findbyadunit(list.getAdunit_id());
		List<EndpointResponseDTO> response = aduend.stream().map(id->MapToDTO(id.getEndpoint_id())).collect(Collectors.toList());
		api.setData(response);
		api.setMessage("Endpoint_List_Get_Successfully");
		api.setMsgCode("ENDPOINT_LIST_GET_SUCCESSFULLY");
		return api;
	}
	
	private EndpointResponseDTO MapToDTO(UUID endpoint_id) {
		EndpointResponseDTO response = new EndpointResponseDTO();
		
		EndPoint end = endrepo.findById(endpoint_id).orElse(null);
		response.setDemand_partner(end.getDemand_partner());
		if(end.getDemand_partner()!=null) {
		Dsp dsp = dsprepo.findById(end.getDemand_partner()).orElse(null);
		response.setDemand_partner_name(dsp.getAdExchange_name());
		}
		response.setEndpoint_name(end.getEndpoint_name());
		response.setEndpoint_id(end.getEndpoint_id());
		response.setBidfloor(end.getBid_floor());
		response.setAdtype(end.getAdtype());
		response.setDsp_params(end.getDsp_params());
		response.setSeller_id(end.getSeller_id());
		
		List<Configurations> allObj = configrepo.findAll();
		Configurations config = allObj.get(0);
		DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(config.getConfigValue());
		String arr = newYorkDateFormatter.format(ZonedDateTime.of(end.getCreated_at(), ZoneId.of("UTC-4")));
        response.setCreated_at(arr);
		response.setCreated_by(end.getCreated_by());

		String arr1 = newYorkDateFormatter.format(ZonedDateTime.of(end.getUpdated_at(), ZoneId.of("UTC-4")));
        response.setUpdated_at(arr1);
        response.setUpdated_by(end.getUpdated_by());
        
        if(end.getDeleted_at()!=null) {
		String arr2 = newYorkDateFormatter.format(ZonedDateTime.of(end.getDeleted_at(), ZoneId.of("UTC-4")));
		response.setDeleted_at(arr2);
        }
		
        response.setIs_deleted(end.getIs_deleted());
        response.setDeleted_by(end.getDeleted_by());
		return response;
	}
	
}
