package com.hepl.tunefortwo.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.http.HttpStatus;
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.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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.hepl.tunefortwo.dto.GenericData;
import com.hepl.tunefortwo.dto.GenericResponse;
import com.hepl.tunefortwo.dto.PaymentDetailsDto;
import com.hepl.tunefortwo.dto.PaymentOrderDto;
import com.hepl.tunefortwo.dto.RefundRequestDto;
import com.hepl.tunefortwo.entity.MasterPayment;
import com.hepl.tunefortwo.entity.PaymentTransaction;
import com.hepl.tunefortwo.service.MasterPaymentService;
import com.hepl.tunefortwo.service.RefundRequestService;
import com.hepl.tunefortwo.utils.JwtUtils;

import java.awt.print.Pageable;
import com.razorpay.Payment;
import com.razorpay.RazorpayException;

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

@Tag(name = "Manage Master Payment", description = "")
//@SecurityRequirement(name = "Bearer Authentication")
@RestController
@RequestMapping("/v1/masterpayment")
@Slf4j
public class MasterPaymentController {

	private final MasterPaymentService masterPaymentService;
	private final RefundRequestService refundRequestService;
	private final JwtUtils jwtUtils;

	public MasterPaymentController(MasterPaymentService masterPaymentService,
			RefundRequestService refundRequestService,JwtUtils jwtUtils) {
		this.masterPaymentService = masterPaymentService;
		this.refundRequestService = refundRequestService;
		this.jwtUtils =jwtUtils;
	}

	@PostMapping("/createOrder")
	public Map<String, String> createOrder(@RequestParam double amount, String formId) throws MessagingException {
		try {
			return masterPaymentService.createOrder(amount, formId);
		} catch (RazorpayException e) {
			throw new RuntimeException("Failed to create order", e);
		}
	}

	@PostMapping("/handle")
	public String handlePayment(@RequestBody PaymentDetailsDto paymentDetails,
			@RequestHeader(value = "x-razorpay-signature", required = false) String razorpaySignature)
			throws RazorpayException, JsonMappingException, JsonProcessingException, MessagingException {
		// Extract parameters from the request
		String paymentId = paymentDetails.getPayment_id();
		String orderId = paymentDetails.getOrder_id();
//        String originalOrderId = paymentDetails.getOriginalOrder_Id();

		// Verify payment
		String paymentUpdateStatus = masterPaymentService.setPaymentsForAnOrderId(paymentId, razorpaySignature);
//        boolean isPaymentVerified = masterPaymentService.verifyPayment(paymentId, orderId, razorpaySignature);
//
//      
		return paymentUpdateStatus;
	}

//	@GetMapping("/getPayments/{orderId}")
//	public GenericResponse getAllPaymentsForOrderId(@PathVariable String orderId) {
//		List<PaymentTransaction> foundPayments = masterPaymentService.getPaymentsForOrderId(orderId);
//		GenericResponse response = new GenericResponse(true);
//		GenericData data = new GenericData();
//		int count = foundPayments.size();
//		Map<String, Object> paymentsMap = new HashMap();
//		paymentsMap.put("count", count);
//		paymentsMap.put("payments", foundPayments);
//		data.setListOfPaymemnts(paymentsMap);
//		response.setData(data);
//		return response;
//
//	}

//	@GetMapping("/getPayments/by-user")
//	public List<MasterPayment> getPaymentsByUserName(@RequestParam String userName) {
//		return masterPaymentService.getPaymentsByUserName(userName);
//	}
//
//	@GetMapping("/getPayments/by-formId")
//	public List<MasterPayment> getPaymentsByFormId(@RequestParam String formId) {
//		return masterPaymentService.getPaymentsByFormId(formId);
//	}

	@GetMapping("/getOrdersByStatus")
	public Map<String, Object> getPaymentsByStatus(@RequestParam String status, Authentication authentication) {
		if (authentication == null || !authentication.isAuthenticated()) {
			throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		}
		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) {
		
		Map<String, Object> paymentsFound = masterPaymentService.getPaymentsWithBYStatus(status);
		return masterPaymentService.getPaymentsWithBYStatus(status);
		} else {
			 throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "You dont have the previllege to view this information");
		}
	}

	@GetMapping("/getallorders")
	public Map<String, Object> getAllOrders(@RequestParam(defaultValue = "0") int page,
	        @RequestParam(defaultValue = "10") int size, 
	        @RequestParam(defaultValue = "id") String sortBy,
	        @RequestParam(defaultValue = "asc") String sortDirection,
	        @RequestParam(required = false) String searchQuery,
	        @RequestParam(required = false) String status,
	        Authentication authentication) {

		if (authentication == null || !authentication.isAuthenticated()) {
			throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		}
		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) {
		Sort.Direction direction = sortDirection.equalsIgnoreCase("desc") ? Sort.Direction.DESC : Sort.Direction.ASC;
		org.springframework.data.domain.Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sortBy));

		return masterPaymentService.getAllOrders(pageable,status,searchQuery);
		}
		else {
			 throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "You dont have the previllege to view this information");
		}
	}

//	@GetMapping("/getPayments/by-paymentId")
//	public PaymentTransaction getPaymentBYItsId(@RequestParam String paymentId) {
//		return masterPaymentService.findPaymentById(paymentId);
//
//	}
//
//	@GetMapping("/getPayments/searchbypaymentid")
//	public List<PaymentTransaction> searchPayments(@RequestParam("query") String query) {
//		List<PaymentTransaction> payments = masterPaymentService.searchPaymentsByPaymentId(query);
//		return payments;
//	}
//
//	@GetMapping("/getPayments/generalSearch")
//	public List<PaymentTransaction> genericSearch(@RequestParam("query") String query) {
//		List<PaymentTransaction> payments = masterPaymentService.genericSearchPayments(query);
//		return payments;
//	}

	@GetMapping("/getPayments/generalOrderSearch")
	public Map<String, Object> genericOrderSearch(@RequestParam("query") String query, Authentication authentication) {
		
		if (authentication == null || !authentication.isAuthenticated()) {
			throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "Unauthorized");
		}
		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) {
		Map<String, Object> payments = masterPaymentService.genericOrderSearch(query);
		return payments;
		}else {
			throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "You dont have the previllege to view this information");
		}
	}

//    @PostMapping("/addRefundRequest")
//    public RefundRequestDto generateRefundRequest(@RequestBody RefundRequestDto refundRequest) {
//    	RefundRequestDto refundRequestData = refundRequestService.addRefundRequest(refundRequest);
//		return refundRequestData;
//    }
//    
//    @PutMapping("/manageRefundRequest")
//    public RefundRequestDto handleRefundRequest(@RequestBody RefundRequestDto refundRequest) throws RazorpayException {
//    	RefundRequestDto refundRequestResponse = refundRequestService.manageRefundRequest(refundRequest);
//		return refundRequestResponse;
//    }
//    
//    @GetMapping("/getAllRefundRequests")
//    public List<RefundRequestDto> allrefundRequests(
//            @RequestParam(defaultValue = "0") int page,
//            @RequestParam(defaultValue = "10") int size,
//            @RequestParam(defaultValue = "id") String sortBy,
//            @RequestParam(defaultValue = "asc") String sortDirection){
//    	Sort.Direction direction = sortDirection.equalsIgnoreCase("desc") ? Sort.Direction.DESC : Sort.Direction.ASC;
//    	org.springframework.data.domain.Pageable pageable = PageRequest.of(page, size,Sort.by(direction, sortBy));
//    	List<RefundRequestDto> requestsFound = refundRequestService.getAllRefundRequests();
//    	return requestsFound;
//    }
//    
//    @GetMapping("/getRefundRequestByStatus")
//    public List<RefundRequestDto> fetchRefundRequestsByStatus(@RequestParam String status){
//    	List<RefundRequestDto> foundRequests = refundRequestService.getRefundRequestsByStatus(status);
//		return foundRequests;
//    	
//    }
//    
//    @GetMapping("/getRefundRequestById/{refundId}")
//    public RefundRequestDto foundRefundRequest(@PathVariable String refundId) {
//    	RefundRequestDto foundRequest = refundRequestService.getRequestById(refundId);
//		return foundRequest;
//    	
//    }

}
