package com.example.demo.service.impl;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.common.APIResponse;
import com.example.demo.dto.BidderCreateDTO;
import com.example.demo.dto.BidderDeleteDTO;
import com.example.demo.dto.BidderResponseDTO;
import com.example.demo.dto.BidderUpdateDTO;
import com.example.demo.entity.Bidder;
import com.example.demo.entity.Configurations;
import com.example.demo.redisentity.BidderRedis;
import com.example.demo.repository.BidderRepository;
import com.example.demo.repository.ConfigurationRepo;
import com.example.demo.service.BidderService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import redis.clients.jedis.Jedis;

@Service
public class BidderServiceImpl implements BidderService {

	@Autowired
	private BidderRepository repo;

	@Autowired
	private ConfigurationRepo configRepo;
	
	@Autowired
	private Jedis jedis;

	@Override
	public APIResponse createbidder(BidderCreateDTO create) throws JsonProcessingException {
		APIResponse api = new APIResponse();

		Bidder bid = new Bidder();
		bid.setBidder_code(create.getBidder_code());
		bid.setBidder_name(create.getBidder_name());

		ObjectMapper mapper = new ObjectMapper();
		String value = mapper.writeValueAsString(create.getBidder_parameters());

		bid.setBidder_parameters(value);
		bid.setCreated_at(LocalDateTime.now());
		bid.setUpdated_at(LocalDateTime.now());
		bid.setCreated_by(create.getCreated_by());
		repo.save(bid);
		
		BidderRedis bidderredis = new BidderRedis();
		
		bidderredis.setBidder_id(bid.getBidder_id());
		UUID id = bidderredis.getBidder_id();
		String id_str = id.toString();
		
		bidderredis.setBidder_name(bid.getBidder_name());
		String name_str = bidderredis.getBidder_name();
		
		bidderredis.setBidder_code(bid.getBidder_code());
		String bidder_code_str = bidderredis.getBidder_code();
		
		bidderredis.setBidder_parameters(bid.getBidder_parameters());
		String bidder_parameters_str = bidderredis.getBidder_parameters();
		
		bidderredis.setCreated_at(bid.getCreated_at());
		LocalDateTime now = bidderredis.getCreated_at();

		String[] arr = new String[2];

		arr[0] = now.toString();

		arr[1] = now.format(DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH));
		String created_at_str = Arrays.toString(arr);
		
		bidderredis.setCreated_by(bid.getCreated_by());
		UUID created_by = bidderredis.getCreated_by();
		String created_by_str = created_by.toString();
		
		bidderredis.setUpdated_at(bid.getUpdated_at());
		LocalDateTime now1 = bidderredis.getUpdated_at();

		String[] arr1 = new String[2];

		arr1[0] = now1.toString();

		arr1[1] = now1.format(DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH));
		String updated_at_str = Arrays.toString(arr);

		String key ="Bidder_"+bid.getBidder_id();
		Map<String,String> map = new HashMap<>();
		map.put("bidder_id", id_str);
		map.put("name", name_str);
		map.put("bidder_code",bidder_code_str);
		map.put("bidder_parameters",bidder_parameters_str);
		map.put("created_at",created_at_str);
		map.put("created_by",created_by_str);
		map.put("updated_at",updated_at_str);
		jedis.hmset(key, map);
		
        api.setData(bid);
		api.setMessage("Bidder Created Successfully");
		api.setMsgCode("BIDDER CREATED SUCCESSFULLY");
		return api;
	}

	@Override
	public APIResponse updatebidder(BidderUpdateDTO update, UUID bidder_id) throws JsonProcessingException {
		APIResponse api = new APIResponse();
		Bidder bid = repo.findById(bidder_id).orElse(null);
		if (bid == null) {
			api.setMessage("Bidder Id Is Not Found");
			api.setMsgCode("BIDDER ID IS NOT FOUND");
			return api;
		} else {
			bid.setBidder_name(update.getBidder_name());
			bid.setBidder_code(update.getBidder_code());
			ObjectMapper mapper = new ObjectMapper();
			String bidder = mapper.writeValueAsString(update.getBidder_parameters());
			bid.setBidder_parameters(bidder);
			bid.setUpdated_at(LocalDateTime.now());
			bid.setUpdated_by(update.getUpdated_by());
			repo.save(bid);
			
			BidderRedis bidderredis = new BidderRedis();
			
			bidderredis.setBidder_id(bid.getBidder_id());
			UUID id = bidderredis.getBidder_id();
			String id_str = id.toString();
			
			bidderredis.setBidder_name(bid.getBidder_name());
			String name_str = bidderredis.getBidder_name();
			
			bidderredis.setBidder_code(bid.getBidder_code());
			String bidder_code_str = bidderredis.getBidder_code();
			
			bidderredis.setBidder_parameters(bid.getBidder_parameters());
			String bidder_parameters_str = bidderredis.getBidder_parameters();
			
			bidderredis.setCreated_at(bid.getCreated_at());
			LocalDateTime now = bidderredis.getCreated_at();

			String[] arr = new String[2];

			arr[0] = now.toString();

			arr[1] = now.format(DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH));
			String created_at_str = Arrays.toString(arr);
			
			bidderredis.setCreated_by(bid.getCreated_by());
			UUID created_by = bidderredis.getCreated_by();
			String created_by_str = created_by.toString();
			
			bidderredis.setUpdated_at(bid.getUpdated_at());
			LocalDateTime now1 = bidderredis.getUpdated_at();

			String[] arr1 = new String[2];

			arr1[0] = now1.toString();

			arr1[1] = now1.format(DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH));
			String updated_at_str = Arrays.toString(arr);
			
			bidderredis.setUpdated_by(bid.getUpdated_by());
			UUID updated_by =  bidderredis.getUpdated_by();
			String updated_by_str = updated_by.toString();

			String key ="Bidder_"+bid.getBidder_id();
			Map<String,String> map = new HashMap<>();
			map.put("bidder_id", id_str);
			map.put("name", name_str);
			map.put("bidder_code",bidder_code_str);
			map.put("bidder_parameters",bidder_parameters_str);
			map.put("created_at",created_at_str);
			map.put("created_by",created_by_str);
			map.put("updated_at",updated_at_str);
			map.put("updated_by",updated_by_str);
			jedis.hmset(key, map);

            api.setData(bid);
			api.setMessage("Bidder Updated Successfully");
			api.setMsgCode("BIDDER UPDATED SUCCESSFULLY");
			return api;
		}
	}

	@Override
	public APIResponse getbyId(UUID bidder_id) {
		APIResponse api = new APIResponse();
		Bidder bid = repo.findById(bidder_id).orElse(null);
		if (bid == null) {
			api.setMessage("Bidder Id Not Found");
			api.setMsgCode("BIDDER ID NOT FOUND");
			return api;
		} else {
			BidderResponseDTO response = MapToDTO(bid);
            api.setData(response);
			api.setMessage("Bidder Get Successfully");
			api.setMsgCode("BIDDER GET SUCCESSFULLY");
			return api;
		}
	}

	@Override
	public APIResponse getall() {
		APIResponse api = new APIResponse();
		List<Bidder> bid = repo.findAll();
		List<BidderResponseDTO> response = bid.stream().map(use -> MapToDTO(use)).collect(Collectors.toList());
        api.setData(response);
		api.setMessage("List Of Bidder Get Successfully");
		api.setMsgCode("LIST OF BIDDER GET SUCCESSFULLY");
		return api;
	}

	@Override
	public APIResponse deletebidder(BidderDeleteDTO delete) {
		APIResponse api = new APIResponse();
        Bidder bid = repo.findById(delete.getBidder_id()).orElse(null);
		if (bid == null) {
			api.setMessage("Bidder Id Not Found");
			api.setMsgCode("BIDDER ID NOT FOUND");
			return api;
		} else {
			bid.setIs_deleted(1);
			bid.setDeleted_at(LocalDateTime.now());
			bid.setDeleted_by(delete.getDeleted_by());
			repo.save(bid);
			
			BidderRedis bidderredis = new BidderRedis();
			
			bidderredis.setIs_deleted(bid.getIs_deleted());
			int is_deleted = bidderredis.getIs_deleted();
			String is_deleted_str = Integer.toString(is_deleted);
			
			bidderredis.setDeleted_at(bid.getDeleted_at());
			LocalDateTime now = bidderredis.getDeleted_at();

			String[] arr = new String[2];

			arr[0] = now.toString();

			arr[1] = now.format(DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH));
			String deleted_at_str = Arrays.toString(arr);
			
			bidderredis.setDeleted_by(bid.getDeleted_by());
			UUID deleted_by = bidderredis.getDeleted_by();
			String deleted_by_str = deleted_by.toString();
			
			String Key ="Bidder_"+bid.getBidder_id();
			Map<String,String> map = new HashMap<>();
			map.put("is_deleted", is_deleted_str);
			map.put("deleted_at", deleted_at_str);
			map.put("deleted_by",deleted_by_str);
			jedis.hmset(Key, map);

            api.setData(bid);
			api.setMessage("Bidder Deleted Successfully");
			api.setMsgCode("BIDDER DELETED SUCCESSFULLY");
			return api;
		}
	}

	private BidderResponseDTO MapToDTO(Bidder bidder) {
		BidderResponseDTO bid = new BidderResponseDTO();
		bid.setBidder_id(bidder.getBidder_id());
		bid.setBidder_code(bidder.getBidder_code());
		bid.setBidder_name(bidder.getBidder_name());
		bid.setBidder_parameters(bidder.getBidder_parameters());
        bid.setUpdated_by(bidder.getUpdated_by());
		bid.setDeleted_by(bidder.getDeleted_by());

		List<Configurations> allObj = configRepo.findAll();
		Configurations config = allObj.get(0);
		DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(config.getConfigValue());
		String arr = newYorkDateFormatter.format(ZonedDateTime.of(bidder.getCreated_at(), ZoneId.of("UTC-4")));
		bid.setCreated_by(bidder.getCreated_by());
		bid.setCreated_at(arr);

		String arr1 = newYorkDateFormatter.format(ZonedDateTime.of(bidder.getUpdated_at(), ZoneId.of("UTC-4")));
		bid.setUpdated_at(arr1);
		bid.setCreated_by(bidder.getCreated_by());

		if (bidder.getDeleted_at() != null) {
			String arr2 = newYorkDateFormatter.format(ZonedDateTime.of(bidder.getDeleted_at(), ZoneId.of("UTC-4")));
			bid.setDeleted_at(arr2);
		}
		bid.setIs_deleted(bidder.getIs_deleted());
		bid.setDeleted_by(bidder.getDeleted_by());
		return bid;

	}

}
