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.CampaignAdunitLinkDTO;
import com.example.demo.dto.CampaignAdunitListDTO;
import com.example.demo.dto.CampignResponseDTO;
import com.example.demo.entity.Adunits;
import com.example.demo.entity.Advertriser;
import com.example.demo.entity.CampaignAdunit;
import com.example.demo.entity.Campign;
import com.example.demo.entity.Configurations;
import com.example.demo.entity.Environment;
import com.example.demo.repository.AdunitRepository;
import com.example.demo.repository.AdvertriserRepo;
import com.example.demo.repository.CampaignAdunitRepo;
import com.example.demo.repository.CampignRepository;
import com.example.demo.repository.ConfigurationRepo;
import com.example.demo.repository.EnvironmentRepo;
import com.example.demo.service.CampaignAdunitService;

import redis.clients.jedis.Jedis;

@Service
public class CampaignAdunitServiceImpl implements CampaignAdunitService {

	@Autowired
	private CampignRepository campaignrepo;

	@Autowired
	private AdunitRepository adunitrepo;

	@Autowired
	private AdvertriserRepo addrepo;

	@Autowired
	private CampaignAdunitRepo repo;

	@Autowired
	private EnvironmentRepo envrepo;

	@Autowired
	private ConfigurationRepo configrepo;

	@Autowired
	private Jedis jedis;

	@Override
	public APIResponse createlink(CampaignAdunitLinkDTO create) {
		APIResponse api = new APIResponse();

		Campign camp = campaignrepo.findById(create.getCampaign_id()).orElse(null);
		Adunits adu = adunitrepo.findById(create.getAdunit_id()).orElse(null);

		if (camp.getEnv_type() != adu.getEnv_type()) {
			api.setMessage("Campaign_Adunit_Not_Linked");
			api.setMsgCode("CAMPAIGN_ADUNIt_NOT_LINKED");
			return api;
		}
		CampaignAdunit campadu = new CampaignAdunit();
		campadu.setCampaign_id(create.getCampaign_id());
		campadu.setAdunit_id(create.getAdunit_id());
		repo.save(campadu);

		String key = "Campaign_Adunit_" + campadu.getAdunit_id();
		List<CampaignAdunit> campList = repo.findbyadunit(campadu.getAdunit_id());
		List<UUID> camapaignidlist = campList.stream().map(id -> id.getCampaign_id()).collect(Collectors.toList());
		JSONArray ja = new JSONArray();
		for (UUID id : camapaignidlist) {
			JSONObject obj = new JSONObject();
			obj.put("campaign_id", id.toString());
			ja.add(obj);
		}
		Map<String, String> map = new HashMap<>();
		map.put("connectedCampaign", ja.toString());
		jedis.hmset(key, map);

		api.setData(campadu);
		api.setMessage("Campaign_Adunit_Linked_Successfully");
		api.setMsgCode("CAMPAIGN_ADUNIT_LINKED_SUCCESSFULLY");

		return api;
	}

	@Override
	public APIResponse deletelink(CampaignAdunitLinkDTO delete) {
		APIResponse api = new APIResponse();

		CampaignAdunit camp = repo.findbyCampaignAndAdunit(delete.getCampaign_id(), delete.getAdunit_id());
		repo.delete(camp);

		String key = "Campaign_Adunit_" + camp.getAdunit_id();
		jedis.del(key);
		List<CampaignAdunit> campList = repo.findbyadunit(camp.getAdunit_id());
		List<UUID> camapaignidlist = campList.stream().map(id -> id.getCampaign_id()).collect(Collectors.toList());
		JSONArray ja = new JSONArray();
		for (UUID id : camapaignidlist) {
			JSONObject obj = new JSONObject();
			obj.put("campaign_id", id.toString());
			ja.add(obj);
		}
		Map<String, String> map = new HashMap<>();
		map.put("connectedCampaign", ja.toString());
		jedis.hmset(key, map);

		api.setMessage("Campaign_Adunit_Unlinked_Successfully");
		api.setMsgCode("CAMPAIGN_ADUNIT_UNLINKED_SUccessFULLY");
		return api;
	}

	@Override
	public APIResponse list(CampaignAdunitListDTO adunit) {
		APIResponse api = new APIResponse();

		List<CampaignAdunit> list = repo.findbyadunit(adunit.getAdunit_id());
		List<CampignResponseDTO> response = list.stream().map(us -> MapToDto(us.getCampaign_id()))
				.collect(Collectors.toList());

		api.setData(response);
		api.setMessage("Campaign_List_Get_Succesfully");
		api.setMsgCode("CAMPAIGN_LIST_GET_Successfully");
		return api;
	}

	private CampignResponseDTO MapToDto(UUID campa) {
		Campign camp = campaignrepo.findById(campa).orElse(null);

		CampignResponseDTO response = new CampignResponseDTO();
		response.setCampign_id(camp.getCampign_id());
		response.setCampign_name(camp.getCampign_name());

		Advertriser ad = addrepo.findById(camp.getAdvertiser_id()).orElse(null);
		response.setAdvertiser_id(camp.getAdvertiser_id());
		response.setAdvertiser_name(ad.getAdvertiser_name());
		response.setBid_price(camp.getBid_price());
		response.setTotal_budget(camp.getCampaignBudget());
		response.setDaliy_budget(camp.getDailyBudget());
		response.setTotal_impression(camp.getTotal_impression());
		response.setDaily_impression(camp.getDaily_impression());
		response.setDuration(camp.getDuration());

		Environment env = envrepo.findById(camp.getEnv_type()).orElse(null);
		response.setEnv_type(env.getName());
		response.setEnv_id(camp.getEnv_type());
		List<Configurations> allObj = configrepo.findAll();
		Configurations config = allObj.get(0);
		DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(config.getConfigValue());
		String arr = newYorkDateFormatter.format(ZonedDateTime.of(camp.getCreated_at(), ZoneId.of("UTC-4")));
		response.setCreated_at(arr);
		response.setCreated_by(camp.getCreated_by());

		String arr1 = newYorkDateFormatter.format(ZonedDateTime.of(camp.getUpdated_at(), ZoneId.of("UTC-4")));
		response.setUpdated_at(arr1);
		response.setUpdated_by(camp.getUpdated_by());

		if (camp.getDeleted_at() != null) {
			String arr2 = newYorkDateFormatter.format(ZonedDateTime.of(camp.getDeleted_at(), ZoneId.of("UTC-4")));
			response.setDeleted_at(arr2);
		}
		response.setIs_deleted(camp.getIs_deleted());
		response.setDeleted_by(camp.getDeleted_by());

		if (camp.getStatus() == 0) {
			response.setStatus("InActive");
		} else if (camp.getStatus() == 1) {
			response.setStatus("Active");
		}

		return response;
	}
}
