package it.enea.cruise.repositories;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import it.enea.cruise.dto.RoleDTO;
import it.enea.cruise.dto.CommunityDTO;
import it.enea.cruise.dto.DeviceDTO;
import it.enea.cruise.dto.LocalUserDTO;
import it.enea.cruise.dto.MetadataDTO;
import it.enea.cruise.model.structure.ColumnCommentDTO;
import it.enea.cruise.model.structure.VwTableMetadata;
import it.enea.cruise.model.user.Community;
import it.enea.cruise.model.user.Device;
import it.enea.cruise.model.user.User;
import it.enea.cruise.model.user.UserCommunity;
import it.enea.cruise.model.user.UserRole;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;

@Getter
@Setter
@NoArgsConstructor
@Log4j2
@Service
@Controller
public class DTOManager {

	@Autowired
	ObjectMapper objectMapper;

	public RoleDTO roleDTO(UserRole userRole) {
		RoleDTO roleDTO = new RoleDTO();
		log.info("preparing RoleDTO for export");

		roleDTO.setCommunityID(userRole.getCommunityid());
		roleDTO.setDescription(userRole.getRole().getDescription());
		roleDTO.setRoleID(userRole.getRole().getId());
		roleDTO.setRoleName(userRole.getRole().getRolename());
		return roleDTO;
	}

	public CommunityDTO communityDTO(UserCommunity c) {
		CommunityDTO communityDTO = new CommunityDTO();
		log.info("preparing CommunityTO for export");
		communityDTO.setCommunityid(c.getCommunity().getCommunityid());
		communityDTO.setDescription(c.getCommunity().getDescription());
		communityDTO.setWallet(c.getWallet() != null ? c.getWallet().toString() : "noWallet");
		communityDTO.setCommunityName(c.getCommunity().getCommunityName());

		return communityDTO;
	}

	public CommunityDTO communityDTO(Community c) {
		CommunityDTO communityDTO = new CommunityDTO();
		log.info("preparing CommunityTO for export");
		communityDTO.setCommunityid(c.getCommunityid());
		communityDTO.setDescription(c.getDescription());
		communityDTO.setWallet("noWallet");
		communityDTO.setCommunityName(c.getCommunityName());

		return communityDTO;
	}

	public DeviceDTO deviceDTO(Device d) {

		DeviceDTO deviceDTO = new DeviceDTO();
		log.info("preparing RoleDTO for export");
		deviceDTO.setActivationdate(d.getActivationdate());
		deviceDTO.setAltdeviceid(d.getAltdeviceid());
		deviceDTO.setDescription(d.getDescription());
		deviceDTO.setDeviceid(d.getDeviceid());
		deviceDTO.setDevicename(d.getDevicename());
		deviceDTO.setDevicestatus(d.getDevicestatus());
		deviceDTO.setDevicetype(d.getDevicetype());
		deviceDTO.setGeoreferenceformat(d.getGeoreferenceformat());
		deviceDTO.setGeoreferencex(d.getGeoreferencex());
		deviceDTO.setGeoreferencey(d.getGeoreferencey());
		deviceDTO.setGeoreferencez(d.getGeoreferencez());
		deviceDTO.setIdentificationmethod(d.getIdentificationmethod());
		deviceDTO.setNote(d.getNote());
		deviceDTO.setSupplierid(d.getSupplierid());

		return deviceDTO;
	}

	public LocalUserDTO userDTO(User user) {

		List<RoleDTO> userRoleDTOList = new ArrayList<RoleDTO>();
		List<CommunityDTO> userCommunityDTOList = new ArrayList<CommunityDTO>();
		List<DeviceDTO> userDeviceDTOList = new ArrayList<DeviceDTO>();

		LocalUserDTO lUserDTO = new LocalUserDTO();

		lUserDTO.setUserid(user.getUserid());
		lUserDTO.setName(user.getName());
		lUserDTO.setOrganization(user.getOrganization());
		lUserDTO.setSubject(user.getSubject());
		lUserDTO.setSurname(user.getSurname());
		lUserDTO.setToken(user.getToken());
		lUserDTO.setEmail(user.getEmail());
		lUserDTO.setPhone(user.getPhone());

		if (user.getUserroles() !=null) {
			for (UserRole ur : user.getUserroles()) {
				RoleDTO roleDTO = new RoleDTO();
				roleDTO = roleDTO(ur);
				log.info(roleDTO);
				RoleDTO role = new RoleDTO();
                role.setRoleName(roleDTO.getRoleName());
                role.setRoleID(roleDTO.getRoleID());
                role.setCommunityID(roleDTO.getCommunityID());
                role.setDescription(roleDTO.getDescription());

                roleDTO.setRole(role);

				userRoleDTOList.add(roleDTO);
			}
		}
		if (user.getUsercommunities() !=null) {
			for (UserCommunity uc : user.getUsercommunities()) {
				CommunityDTO cDTO = new CommunityDTO();
				cDTO = communityDTO(uc);
				log.info(cDTO);
				userCommunityDTOList.add(cDTO);
			}
		}
		if (user.getDevices() !=null) {
			for (Device d : user.getDevices()) {
				DeviceDTO dDTO = new DeviceDTO();
				dDTO = deviceDTO(d);
				log.info(dDTO);
				userDeviceDTOList.add(dDTO);
			}
		}

		lUserDTO.setUserroles(userRoleDTOList);
		lUserDTO.setUsercommunities(userCommunityDTOList);
		lUserDTO.setUserdevices(userDeviceDTOList);

		return lUserDTO;
	}

	public MetadataDTO mtDataDTO(VwTableMetadata mData, String language) {
		objectMapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
		MetadataDTO mtDataDTO = new MetadataDTO();
		ColumnCommentDTO ccDTO = new ColumnCommentDTO();
		String comment = "";
		log.info(mData.getColumnName());
		String cComment = mData.getColumnComment();
		if (mData.getColumnComment() != null && mData.getColumnComment().length() > 0) {
			log.info(mData.getColumnComment());
			if (cComment.contains("JSON:")) {
				cComment = cComment.split("JSON:")[1];
			}
			try {
				ccDTO = objectMapper.readValue(cComment, ColumnCommentDTO.class);
				log.info(ccDTO);
			} catch (JsonProcessingException e) {
				// TODO Auto-generated catch block

				log.info(e.getLocalizedMessage());
				return mtDataDTO;

			}

			if (ccDTO.getDescription() != null && ccDTO.getDescription().size() > 0) {
				if (ccDTO.getDescriptionOrdered().containsKey(language)) {
					mtDataDTO.setDescriptionShort(ccDTO.getDescriptionOrdered().get(language).getShortDescription());				
					mtDataDTO.setDescriptionLong(ccDTO.getDescriptionOrdered().get(language).getLongDescription());
				}else {
					String shortDesc = ccDTO.getDescriptionOrdered().get("en") != null  ?
							ccDTO.getDescriptionOrdered().get("en").getShortDescription() : "";
					String longDesc = ccDTO.getDescriptionOrdered().get("en") != null ?
							ccDTO.getDescriptionOrdered().get("en").getLongDescription() : "";

					mtDataDTO.setDescriptionShort(shortDesc);				
					mtDataDTO.setDescriptionLong(longDesc);

				}
			}else {
				mtDataDTO.setDescriptionShort("No value");				
				mtDataDTO.setDescriptionLong("No value");

			}
		}
		if (ccDTO.isColumnProtected()) {
			mtDataDTO.setColumnProtected(true);
		}

		mtDataDTO.setLanguage(language);
		mtDataDTO.setColumnName(mData.getColumnName());
		mtDataDTO.setColumnDefault(mData.getColumnDefault());

		//mtDataDTO.setDescriptionLong(comment);
		mtDataDTO.setExample(ccDTO.getExample());

		mtDataDTO.setDataType(convertDataTypeToGeneralType(mData.getDataType()));
		mtDataDTO.setIs_Nullable(mData.getIsNullable());
		// mtDataDTO.setIsIdentity(mData.getIsIdentity());
		// mtDataDTO.setTableDescription(mData.getTableDescription());

		objectMapper.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), false);

		return mtDataDTO;

	}

	public String convertDataTypeToGeneralType(String dataType) {
		String generalDataType = "";

		switch (dataType) {
		case "character varying":
			generalDataType = "String";
			break;
		case "integer":
		case "double precision":
			generalDataType = "Number";
			break;
		case "text":
			generalDataType = "String";
			break;
		default :
			generalDataType = "String";
			break;
		}
		return generalDataType;
	}
}
