package com.project.whatsappchatbot.controller;

import com.project.whatsappchatbot.DTO.*;
import com.project.whatsappchatbot.controller.BotController.WhatsAppBotController;
import com.project.whatsappchatbot.model.*;
import com.project.whatsappchatbot.repository.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.*;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Value;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/api")
public class ExternalController {

    private static Logger log = LoggerFactory.getLogger(ExternalController.class);
    @Autowired
    private InvoiceRepository invoiceRepository;

    @Autowired
    private ComplaintRepository complaintRepository;
    @Autowired
    private HelpSupportRepository helpSupportRepository;

    private static final RestTemplate restTemplate = new RestTemplate();
    @Autowired
    private MechanicRepository mechanicRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private ChatMessageRepository chatMessageRepository;

    @Autowired
    private FeedbackRepository feedbackRepository;

    @Autowired
    private AccountRepository accountRepository;

    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private StateRepository stateRepository;

    @Autowired
    private VehicleRepository vehicleRepository;

    @Autowired
    private BrandRepository brandRepository;
    @Autowired
    private ServiceRepository serviceRepository;

    @Autowired
    private AddressRepository addressRepository;
    @Autowired
    private OrderCancellationReasonRepository orderCancellationReasonRepository;
    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private SimpMessagingTemplate template;

    @Autowired
    private VehicleModelRepository vehicleModelRepository;

    @Value("${phone.notification.numbers}")
    private String notificationNumbers;

    private List<String> notificationNumberList;

    @PostConstruct
    public void initPhonesNotificationNumber() {
        if (notificationNumbers != null && !notificationNumbers.isBlank()) {
        	notificationNumberList = Arrays.asList(notificationNumbers.split(","));
			log.info("Notification numbers loaded: {}", notificationNumberList);
        } else {
            notificationNumberList = new ArrayList<>();
            log.warn("No notificationNumberList set in environment.");
        }
    }

    @PostMapping("/newBooking")
    public ResponseEntity<String> notifyOrder(@RequestBody NotifyNewOrderDTO notifyOrderDTO) {
        log.info("Stating notifyOrder method.");
        Long orderId = notifyOrderDTO.getOrderId();
        String recipientNumber = notifyOrderDTO.getRecipientNumber();

        if (orderId == null || recipientNumber == null) {
            return ResponseEntity.badRequest().body("Order ID or recipient number is missing");
        }
        log.info("Fetching data from database");
        Optional<Order> orderEntity = orderRepository.findById(orderId);
        if (orderEntity.isEmpty()) {
            return ResponseEntity.badRequest().body("Order was not found");
        }
        log.info("Processing order with id {}", orderId);
        log.info(String.valueOf(orderEntity.get()));
        log.info("Orders fetched");
        Optional<Service> serviceEntity = serviceRepository.findById(orderEntity.get().getServiceId());
        log.info(String.valueOf(serviceEntity.get()));
        log.info("Services fetched");
        Optional<Address> addressEntity = Optional.of(orderEntity.get().getAddress());
        log.info("Addresses fetched");
        Customer customEntityNotOptional = orderEntity.get().getUser();
        log.info("Customer fetched");
        Optional<Vehicle> vehicleEntity = Optional.of(orderEntity.get().getVehicle());
        log.info("Vehicle fetched");
        Optional<Brand> brandEntity = Optional.of(vehicleEntity.get().getBrand());
        log.info("Brand fetched");
        VehicleModel vehicleModelEntity = vehicleEntity.get().getVehicleModel();
        log.info("Data from database fetched");
        String googleMapsLink = "Google Maps Link : https://www.google.com/maps/search/?api=1&query=" + addressEntity.get().getLatitude() + "," + addressEntity.get().getLongitude();

        log.info("Sending notifications to admins");
        for (String adminNumber : notificationNumberList) {
            log.info("Sending notification to number {}", adminNumber);
            sendNotificationAsync(adminNumber, orderEntity.get(), serviceEntity.get(), brandEntity.get(), vehicleModelEntity, addressEntity.get(), customEntityNotOptional, googleMapsLink);
        }
        log.info("Notifications to admins send successfully");
        log.info("Sending notification to user phone : {}", recipientNumber);
        sendNotificationAsync("+91" + customEntityNotOptional.getPhone(), orderEntity.get(), serviceEntity.get(), brandEntity.get(), vehicleModelEntity, addressEntity.get(), customEntityNotOptional, googleMapsLink);
        log.info("Notification sent");
        log.info("End of notifyOrder method.");
        return ResponseEntity.ok("Notification sent successfully");
    }

    @Async
    public void sendNotificationAsync(String phoneNumber, Order order, Service service, Brand brand,
            VehicleModel vehicleModel, Address address, Customer customer, String googleMapsLink) {
        String status;
        String customerName;
        String customerPhone;
        if (customer == null) {
            customerName = "Not defined";
            customerPhone = "Not defined";
        } else {
            customerName = customer.getName();
            customerPhone = customer.getPhone();
        }
        log.info(order.getDateAndTime());
        log.info(address.getStreet());
        log.info(address.getCity().getName());
        if (order.getStatus() == null) {
            status = "Empty";
        } else {
            status = order.getStatus().getTitle();
        }
        String vehicleModelName = "N/A";
        if (vehicleModel != null) {
            vehicleModelName = vehicleModel.getName();
        }
        WhatsAppBotController.sendTemplateMessageNewBooking(phoneNumber, order.getId().toString(),
                service.getServiceTypeId().getName(), brand.getName(), vehicleModelName, address.getCity().getStateId().getName(),
                address.getCity().getName(), address.getAddress(), order.getDateAndTime(), customerName,
                "+91" + customerPhone, service.getName(), googleMapsLink, status, order.getIsPaid() == 0 ? "Unpaid" : "Paid");
    }

    @PostMapping("/rescheduleBooking")
    public ResponseEntity<String> rescheduleBooking(@RequestBody NotifyRescheduleOrderDTO notifyOrderDTO) {
        Long orderId = notifyOrderDTO.getOrderId();
        String recipientNumber = notifyOrderDTO.getRecipientNumber().trim();

        Optional<Order> orderOptional = orderRepository.findById(orderId);
        if (orderOptional.isEmpty()) {
            return ResponseEntity.badRequest().body("Order not found");
        }
        log.info("Rescheduling order with id {}", orderId);

        Order order = orderOptional.get();
        Customer customer = order.getUser();
        if (customer == null) {
            return ResponseEntity.badRequest().body("Customer not found with phone number: " + recipientNumber);
        }

        Optional<Service> optionalService = serviceRepository.findById(order.getServiceId());
        if (optionalService.isEmpty()) {
            return ResponseEntity.badRequest().body("Not service found for current customer: " + recipientNumber);
        }
        Service service = optionalService.get();

        Vehicle vehicle = order.getVehicle();
        if (vehicle == null) {
            return ResponseEntity.badRequest().body("No vehicle for this order: " + recipientNumber);
        }
        Brand brand = vehicle.getBrand();
        if (brand == null) {
            return ResponseEntity.badRequest().body("No brand specified for current vehicle.");
        }

        VehicleModel vehicleModel = vehicle.getVehicleModel();
        if (vehicleModel == null) {
            return ResponseEntity.badRequest().body("Vehicle model not specified for " + recipientNumber);
        }

        Address address = order.getAddress();

        String googleMapsLink = "Google Maps Link: https://www.google.com/maps/search/?api=1&query="
                + address.getLatitude() + "," + address.getLongitude();

        for (String adminNumber : notificationNumberList) {
            WhatsAppBotController.sendTemplateMessageRescheduled(adminNumber, order.getId().toString(),
                    service.getName(), brand.getName(), vehicleModel.getName(), address.getCity().getStateId().getName(),
                    address.getCity().getName(), address.getStreet(), order.getDateAndTime(), customer.getName(),
                    customer.getPhone(), service.getDescription(), googleMapsLink, order.getStatus2());
        }
        WhatsAppBotController.sendTemplateMessageRescheduled(customer.getPhone(), order.getId().toString(),
                service.getName(), brand.getName(), vehicleModel.getName(), address.getCity().getStateId().getName(),
                address.getCity().getName(), address.getStreet(), order.getDateAndTime(), customer.getName(),
                customer.getPhone(), service.getDescription(), googleMapsLink, order.getStatus2());

        return ResponseEntity.ok("Notification sent successfully");
    }

    @PostMapping("/cancelBooking")
    public ResponseEntity<String> cancelBooking(@RequestBody NotifyCancellationOrderDTO notifyOrderDTO) {
        Long orderId = notifyOrderDTO.getOrderId();
        String recipientNumber = notifyOrderDTO.getRecipientNumber().trim();
        String cancellationReason = notifyOrderDTO.getCancellationReason();
        Optional<Order> orderOptional = orderRepository.findById(orderId);
        if (orderOptional.isEmpty()) {
            return ResponseEntity.badRequest().body("Order not found");
        }

        Order order = orderOptional.get();
        Customer customer = order.getUser();
        if (customer == null) {
            return ResponseEntity.badRequest().body("Customer not found with phone number: " + recipientNumber);
        }

        Optional<Service> optionalService = serviceRepository.findById(order.getServiceId());
        if (optionalService.isEmpty()) {
            return ResponseEntity.badRequest().body("No service found for current order.");
        }
        Service service = optionalService.get();

        String brandName = null;
        String vehicleModelName = null;

        if (order.getVehicle() != null) {
            Vehicle vehicle = order.getVehicle();
            if (vehicle.getBrand() != null) {
                brandName = order.getVehicle().getBrand().getName();
            }
            if (vehicle.getVehicleModel() != null) {
                vehicleModelName = order.getVehicle().getVehicleModel().getName();
            }
        }
        var cancelReason = orderCancellationReasonRepository.findByTitle(cancellationReason);
        if (cancelReason.isEmpty()) {
            var newCancelReason = new OrderCancellationReason();
            newCancelReason.setTitle(cancellationReason);
            newCancelReason.setActive(1);
            orderCancellationReasonRepository.saveAndFlush(newCancelReason);
            order.setOrderCancellationReason(newCancelReason);
        }

        Address address = order.getAddress();

        String googleMapsLink = "Google Maps Link: https://www.google.com/maps/search/?api=1&query="
                + address.getLatitude() + "," + address.getLongitude();

        for (String adminNumber : notificationNumberList) {
            WhatsAppBotController.sendTemplateMessageCanceled(adminNumber, order.getId().toString(),
                    service.getName(), brandName, vehicleModelName, address.getCity().getStateId().getName(),
                    address.getCity().getName(), address.getStreet(), order.getDateAndTime(), customer.getName(),
                    customer.getPhone(), service.getDescription(), googleMapsLink, order.getStatus().getTitle(),
                    cancellationReason);
        }
        WhatsAppBotController.sendTemplateMessageCanceled(customer.getPhone(), order.getId().toString(),
                service.getName(), brandName, vehicleModelName, address.getCity().getStateId().getName(),
                address.getCity().getName(), address.getStreet(), order.getDateAndTime(), customer.getName(),
                customer.getPhone(), service.getDescription(), googleMapsLink, order.getStatus().getTitle(),
                cancellationReason);

        return ResponseEntity.ok("Notification sent successfully");
    }
}
