package com.hepl.tunefortwo.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import com.hepl.tunefortwo.config.i18n.Translator;
import com.hepl.tunefortwo.dto.AccessControlStatus;
import com.hepl.tunefortwo.dto.GenericData;
import com.hepl.tunefortwo.dto.GenericResponse;
import com.hepl.tunefortwo.dto.InstrumentRequestDto;
import com.hepl.tunefortwo.dto.LanguageRequestDto;
import com.hepl.tunefortwo.service.LanguageService;
import com.hepl.tunefortwo.utils.AppMessages;
import com.hepl.tunefortwo.utils.JwtUtils;

import io.jsonwebtoken.Claims;
import io.swagger.v3.oas.annotations.Operation;
//import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.mail.MessagingException;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;

@Tag(name = "Create and Manage Language", description = "")
//@SecurityRequirement(name = "Bearer Authentication")
@RestController
@RequestMapping("/v1/language")
@Slf4j
public class LanguageController {
	
	private final LanguageService languageService;
    private final Translator translator;
    private final JwtUtils jwtUtils;
	
	public LanguageController(LanguageService languageService , Translator translator,JwtUtils jwtUtils) {
		this.languageService = languageService;
		this.translator = translator;
		this.jwtUtils = jwtUtils;
	}
	 @PostMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
	    public GenericResponse addLanguage(@Valid @ModelAttribute LanguageRequestDto data,Authentication authentication)
	            throws MessagingException, IOException {
		 boolean isAdmin = false;
		    if (authentication instanceof JwtAuthenticationToken) {
		        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
		        Jwt jwt = jwtAuthToken.getToken();
		        String tokenValue = jwt.getTokenValue();
		        Claims claims = jwtUtils.extractClaims(tokenValue);
		        String email = claims.getSubject();
		        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
		        if (userDetails != null) {
		            String roleId = (String) userDetails.get("roleId");
		            String userId = (String) userDetails.get("id");
		            if (roleId.equals("1")) {
		                isAdmin = true;
		            }
		        }
		    }

		    if (!isAdmin) {
		        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
		        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		    }
	        log.info("Adding Languge");
	        languageService.saveLanugae(data);
	        GenericResponse response = new GenericResponse(true);
	        response.setMessage(translator.toLocale(AppMessages.LANGUAGE_SAVED));
	        return response;
	    }
	 @GetMapping()
		public GenericResponse getAllLanguage(Authentication authentication) {
		 boolean isAdmin = false;
		    if (authentication instanceof JwtAuthenticationToken) {
		        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
		        Jwt jwt = jwtAuthToken.getToken();
		        String tokenValue = jwt.getTokenValue();
		        Claims claims = jwtUtils.extractClaims(tokenValue);
		        String email = claims.getSubject();
		        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
		        if (userDetails != null) {
		            String roleId = (String) userDetails.get("roleId");
		            String userId = (String) userDetails.get("id");
		            if (roleId.equals("1")) {
		                isAdmin = true;
		            }
		        }
		    }

		    if (!isAdmin) {
		        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
		        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		    }
			log.info("Get all Languages");
			GenericResponse response = new GenericResponse(true);
			GenericData data = new GenericData();
			data.setLanguages(languageService.getAllLanguage());
			response.setData(data);
			return response;
		}
		
		@GetMapping("/get-AllLanguage-Active")
		public GenericResponse getAllLanguageByActive() {
			log.info("Get all languages");
			GenericResponse response = new GenericResponse(true);
			GenericData data = new GenericData();
			data.setLanguages(languageService.getAllLanguageByActive());
			response.setData(data);
			return response;
		}
		
		 @GetMapping("/{id}")
		    public GenericResponse getLanguageById(@PathVariable String id,Authentication authentication) {
			 boolean isAdmin = false;
			    if (authentication instanceof JwtAuthenticationToken) {
			        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
			        Jwt jwt = jwtAuthToken.getToken();
			        String tokenValue = jwt.getTokenValue();
			        Claims claims = jwtUtils.extractClaims(tokenValue);
			        String email = claims.getSubject();
			        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
			        if (userDetails != null) {
			            String roleId = (String) userDetails.get("roleId");
			            String userId = (String) userDetails.get("id");
			            if (roleId.equals("1")) {
			                isAdmin = true;
			            }
			        }
			    }

			    if (!isAdmin) {
			        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
			        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
			    }
		        log.info("Get language");

		        GenericResponse response = new GenericResponse(true);
		        GenericData data = new GenericData();

		        data.setLanguage(languageService.getLanguageById(id));
		        response.setData(data);
		        return response;
		    }
		
		@Operation(summary = "Change action control status")
		@PutMapping("/action-control/{id}")
		public GenericResponse updateActionControlStatus(@RequestParam AccessControlStatus status, @PathVariable String id,Authentication authentication)
				throws MessagingException {
			boolean isAdmin = false;
		    if (authentication instanceof JwtAuthenticationToken) {
		        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
		        Jwt jwt = jwtAuthToken.getToken();
		        String tokenValue = jwt.getTokenValue();
		        Claims claims = jwtUtils.extractClaims(tokenValue);
		        String email = claims.getSubject();
		        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
		        if (userDetails != null) {
		            String roleId = (String) userDetails.get("roleId");
		            String userId = (String) userDetails.get("id");
		            if (roleId.equals("1")) {
		                isAdmin = true;
		            }
		        }
		    }

		    if (!isAdmin) {
		        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
		        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		    }
			log.info("Update language control status ... {}", id);
			languageService.updateActionControlStatus(status, id);
			GenericResponse response = new GenericResponse(true);
			response.setMessage(translator.toLocale(AppMessages.LANGUAGE_STATUS_CHANGED));
			return response;
		}
		
		@Operation(description = "Update Language based on id")
		@PutMapping("/{id}")
		public GenericResponse updateLanguage(@PathVariable String id,
				@Valid @RequestBody LanguageRequestDto language,Authentication authentication) {
			boolean isAdmin = false;
		    if (authentication instanceof JwtAuthenticationToken) {
		        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
		        Jwt jwt = jwtAuthToken.getToken();
		        String tokenValue = jwt.getTokenValue();
		        Claims claims = jwtUtils.extractClaims(tokenValue);
		        String email = claims.getSubject();
		        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
		        if (userDetails != null) {
		            String roleId = (String) userDetails.get("roleId");
		            String userId = (String) userDetails.get("id");
		            if (roleId.equals("1")) {
		                isAdmin = true;
		            }
		        }
		    }

		    if (!isAdmin) {
		        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
		        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		    }
			log.info("Update language ... {}", id);
			languageService.updateLanguage(language, id);
			GenericResponse response = new GenericResponse(true);
			response.setMessage(translator.toLocale(AppMessages.LANGUAGE_UPDATED_SUCCESSFULLY));
			return response;
		}
		
		@DeleteMapping("/{id}")
		public GenericResponse deleteLanguage(@PathVariable String id,Authentication authentication) {
			boolean isAdmin = false;
		    if (authentication instanceof JwtAuthenticationToken) {
		        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
		        Jwt jwt = jwtAuthToken.getToken();
		        String tokenValue = jwt.getTokenValue();
		        Claims claims = jwtUtils.extractClaims(tokenValue);
		        String email = claims.getSubject();
		        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
		        if (userDetails != null) {
		            String roleId = (String) userDetails.get("roleId");
		            String userId = (String) userDetails.get("id");
		            if (roleId.equals("1")) {
		                isAdmin = true;
		            }
		        }
		    }

		    if (!isAdmin) {
		        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
		        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		    }
			log.info("delete language.....{}",id);
			languageService.deleteLanguage(id);
			GenericResponse response = new GenericResponse(true);
			response.setMessage(translator.toLocale(AppMessages.LANGUAGE_DELETED));
			return response;
		}
		
		   @DeleteMapping("/")
		    public GenericResponse deleteAllLanguage(@RequestBody List<String> id,Authentication authentication) {
			   boolean isAdmin = false;
			    if (authentication instanceof JwtAuthenticationToken) {
			        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
			        Jwt jwt = jwtAuthToken.getToken();
			        String tokenValue = jwt.getTokenValue();
			        Claims claims = jwtUtils.extractClaims(tokenValue);
			        String email = claims.getSubject();
			        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
			        if (userDetails != null) {
			            String roleId = (String) userDetails.get("roleId");
			            String userId = (String) userDetails.get("id");
			            if (roleId.equals("1")) {
			                isAdmin = true;
			            }
			        }
			    }

			    if (!isAdmin) {
			        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
			        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
			    }
		        log.info("delete all language.....{}", id);
		        languageService.deleteAllLanguage(id);
		        GenericResponse response = new GenericResponse(true);
		        response.setMessage(translator.toLocale(AppMessages.LANGUAGE_ALL_DELETED));
		        return response;
		    }
		    
			@Operation(summary = "Change all action control status")
			@PutMapping(value ="/action-controls")
			public GenericResponse updateAllActionControlStatus(@RequestParam AccessControlStatus status, @RequestBody List<String> id,Authentication authentication)
					throws MessagingException {
				boolean isAdmin = false;
			    if (authentication instanceof JwtAuthenticationToken) {
			        JwtAuthenticationToken jwtAuthToken = (JwtAuthenticationToken) authentication;
			        Jwt jwt = jwtAuthToken.getToken();
			        String tokenValue = jwt.getTokenValue();
			        Claims claims = jwtUtils.extractClaims(tokenValue);
			        String email = claims.getSubject();
			        Map<String, Object> userDetails = (Map<String, Object>) claims.get("userDetails");
			        if (userDetails != null) {
			            String roleId = (String) userDetails.get("roleId");
			            String userId = (String) userDetails.get("id");
			            if (roleId.equals("1")) {
			                isAdmin = true;
			            }
			        }
			    }

			    if (!isAdmin) {
			        ResponseEntity<String> response = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized");
			        throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
			    }
				log.info("Update instrument control status ... {}", id);
				languageService.updateAllActionControlStatus(status, id);
				GenericResponse response = new GenericResponse(true);
				response.setMessage(translator.toLocale(AppMessages.LANGUAGE_ALL_STATUS_CHANGED));
				return response;
			}

}
