package com.hepl.tunefortwo.controller;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.nio.file.Files;

import javax.sound.sampled.UnsupportedAudioFileException;

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRange;
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.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.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import com.hepl.tunefortwo.dto.GenericData;
import com.hepl.tunefortwo.dto.GenericResponse;
import com.hepl.tunefortwo.dto.WelcomeVideoDto;
import com.hepl.tunefortwo.entity.FileType;
import com.hepl.tunefortwo.service.FileService;
import com.hepl.tunefortwo.service.FiledService;
import com.hepl.tunefortwo.service.WelcomeVideoService;
import com.hepl.tunefortwo.utils.AppMessages;
import com.hepl.tunefortwo.utils.JwtUtils;

import io.jsonwebtoken.Claims;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.mail.MessagingException;
import lombok.extern.slf4j.Slf4j;

@Tag(name = "Add and Manage Welcome Videos", description = "")
//@SecurityRequirement(name = "Bearer Authentication")
@RestController
@RequestMapping("/v1/welcomeVideo")
@Slf4j
public class WelcomeVideoController {

	private final WelcomeVideoService welcomeVideoService;
	private final FileService fileService;
	private final JwtUtils jwtUtils;

	public WelcomeVideoController(WelcomeVideoService welcomeVideoService, FileService fileService,JwtUtils jwtUtils) {
		this.welcomeVideoService = welcomeVideoService;
		this.fileService = fileService;
		this.jwtUtils = jwtUtils;
	}

	@GetMapping("/getAllWelcomeVideos")
	public GenericResponse getVideos() {
		return welcomeVideoService.getWelcomeVideos();
	}

	@PostMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, value="/addVideo")
	public GenericResponse addNewVideo(@ModelAttribute WelcomeVideoDto newVideoData,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");
		    }
		if (newVideoData.getVideoClip() != null) {
			String originalFilename = newVideoData.getVideoClip().getOriginalFilename();
			if (originalFilename != null) {
				String fileExtension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
				List<String> allowedExtensions = Arrays.asList("mp4", "mov", "wmv", "avi", "mkv");
				if (!allowedExtensions.contains(fileExtension)) {
					throw new MessagingException("Only MP4, MOV, AVI, MKV, and WMV files are allowed");
				}
			}

			String filename = fileService.uploadFile(newVideoData.getVideoClip(), FileType.WELCOMEVIDEO);
			newVideoData.setVideoName(filename);
		}

		return welcomeVideoService.addWelcomeVideo(newVideoData);
	}

	@PutMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }, value="/updateVideo/{id}")
	public GenericResponse updateVideoData(@ModelAttribute WelcomeVideoDto updateVideoData,@PathVariable("id") String id,Authentication authentication) throws IOException, 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");
		    }
		return welcomeVideoService.updateWelcomeVideo(updateVideoData,id);
	}

//	@GetMapping("/video/{filename}")
//	public ResponseEntity<byte[]> serveFile(@PathVariable String filename) throws IOException {
//	    log.info("Get filename .. {}", filename);
//
//	    Resource file = fileService.loadAsResource(filename, FileType.WELCOMEVIDEO);
//	    if (file == null) {
//	        throw new ResponseStatusException(HttpStatus.NOT_FOUND, AppMessages.FILE_NOT_FOUND);
//	    }
//
//	    String fileNameNew = file.getFilename();
//	    String modifiedFilename = fileNameNew.replaceAll("^\\d+-", "");
//
//	    String contentType = Files.probeContentType(Paths.get(file.getURI()));
//
//	    if (contentType == null) {
//	        contentType = "application/octet-stream";
//	    }
//
//	    return ResponseEntity.ok()
//	            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + modifiedFilename + "\"")
//	            .header(HttpHeaders.CONTENT_TYPE, contentType)
//	            .body(file.getContentAsByteArray());
//	}
	@GetMapping("/video/{filename}")
	public ResponseEntity<ResourceRegion> serveFile(@PathVariable String filename, @RequestHeader HttpHeaders headers) throws IOException {
	    log.info("Get filename .. {}", filename);
	 
	    Resource file = fileService.loadAsResource(filename, FileType.WELCOMEVIDEO);
	    if (file == null) {
	        throw new ResponseStatusException(HttpStatus.NOT_FOUND, AppMessages.FILE_NOT_FOUND);
	    }
	 
	    long contentLength = file.contentLength();
	    ResourceRegion resourceRegion = resourceRegion(file, headers, contentLength);
	 
	    String contentType = Files.probeContentType(Paths.get(file.getURI()));
	    if (contentType == null) {
	        contentType = "video/mp4";  // Default to MP4 for videos
	    }
	 
	    return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
	            .contentType(MediaType.parseMediaType(contentType))
	            .body(resourceRegion);
	}
	 
	private ResourceRegion resourceRegion(Resource file, HttpHeaders headers, long contentLength) throws IOException {
	    final long chunkSize = 1 * 1024 * 1024; // 1MB chunks
	    if (headers.getRange().isEmpty()) {
	        long rangeStart = 0;
	        long rangeEnd = Math.min(chunkSize, contentLength - 1);
	        return new ResourceRegion(file, rangeStart, rangeEnd - rangeStart + 1);
	    } else {
	        HttpRange range = headers.getRange().get(0);
	        long rangeStart = range.getRangeStart(contentLength);
	        long rangeEnd = Math.min(range.getRangeEnd(contentLength), contentLength - 1);
	        long rangeLength = Math.min(chunkSize, rangeEnd - rangeStart + 1);
	        return new ResourceRegion(file, rangeStart, rangeLength);
	    }
	}
	
	@GetMapping("/getMobileWelcomeVideo")
	public GenericResponse getVideoForMobile() {
		
		return welcomeVideoService.getMobileVideo();
	}
	
	 @GetMapping("/{id}")
	    public GenericResponse getWelcomeVideoById(@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 WelcomeVIdeo By ID");
	        

	       
	        return welcomeVideoService.getWelcomeVideoById(id);
	    }


}
