package com.avitam.bankloanapplication.service.impl;

import com.avitam.bankloanapplication.model.dto.NotificationDto;
import com.avitam.bankloanapplication.model.dto.NotificationWsDto;
import com.avitam.bankloanapplication.model.entity.Customer;
import com.avitam.bankloanapplication.model.entity.Notification;
import com.avitam.bankloanapplication.repository.CustomerRepository;
import com.avitam.bankloanapplication.repository.NotificationHistoryRepository;
import com.avitam.bankloanapplication.repository.NotificationRepository;
import com.avitam.bankloanapplication.repository.UserRepository;
import com.avitam.bankloanapplication.service.NotificationService;
import org.modelmapper.ModelMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Scanner;

@Service
public class NotificationServiceImpl implements NotificationService {
    private static final String ADMIN_NOTIFICATION = "/admin/notification";
    Logger LOG = LoggerFactory.getLogger(NotificationServiceImpl.class);

    @Autowired
    private NotificationRepository notificationRepository;
    @Autowired
    private CustomerRepository customerRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private NotificationHistoryRepository notificationHistoryRepository;


    public Optional<Notification> findNotificationById(String id) {
        return Optional.ofNullable(notificationRepository.findByRecordId(id));
    }

    public Notification getNotificationById(String id) {
        return findNotificationById(id).get();
    }

    public NotificationWsDto handleEdit(NotificationWsDto request) {
        Notification notification = new Notification();
        List<NotificationDto> notificationDtos = request.getNotificationDtoList();
        List<Notification> notifications = new ArrayList<>();
        for (NotificationDto notificationDto : notificationDtos) {
            if (notificationDto.getRecordId() != null) {
                notification = notificationRepository.findByRecordId(notificationDto.getRecordId());
                modelMapper.map(notificationDto, notification);
                notificationRepository.save(notification);
                request.setMessage("Data updated successfully");


            } else {
                notification = modelMapper.map(notificationDto, Notification.class);
                notification.setCreationTime(new Date());
                notification.setStatus(true);
                notificationRepository.save(notification);
            }
            if (request.getRecordId() == null) {
                notification.setRecordId(String.valueOf(notification.getId().getTimestamp()));
            }
            notificationRepository.save(notification);
            notifications.add(notification);
            request.setBaseUrl(ADMIN_NOTIFICATION);
            request.setMessage("Data added Successfully");

        }
        request.setNotificationDtoList(modelMapper.map(notifications, List.class));
        return request;
    }


    public void sendNotificationToCustomer(String title, String message, String notificationId) {
        try {
            //   Customer customer = customerRepository.findByRecordId(customerId);
//            if (customer == null || customer.getNotificationId() == null || customer.getNotificationId().isBlank()) {
//                LOG.warn("Customer or notification ID not found");
//                return;
//            }

            String payload = String.format("""
                        {
                          "app_id": "482fa2be-261b-41df-8176-3873b09daa93",
                          "include_player_ids": ["%s"],
                          "headings": { "en": "%s" },
                          "contents": { "en": "%s" }
                        }
                    """, notificationId, title, message);

            HttpURLConnection con = (HttpURLConnection) new URL("https://onesignal.com/api/v1/notifications").openConnection();
            con.setUseCaches(false);
            con.setDoOutput(true);
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            con.setRequestProperty("Authorization", "Basic os_v2_app_jax2fprgdna57alwhbz3bhnksonddgfho5fug2m3xysekqqqjz4gsa356dvjuwpcl35ete6wi75vz7fwjeagwyuaj4ovjjdx6emalty");

            try (OutputStream os = con.getOutputStream()) {
                os.write(payload.getBytes(StandardCharsets.UTF_8));
            }

            int status = con.getResponseCode();
            try (Scanner scanner = new Scanner(
                    status >= 200 && status < 400 ? con.getInputStream() : con.getErrorStream(), StandardCharsets.UTF_8)) {
                String response = scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
                LOG.debug("OneSignal Response for customer: {}", response);
            }
            Customer customer = customerRepository.findByNotificationId(notificationId);
            if (customer != null) {
                Notification history = new Notification();
                history.setUserId(customer.getRecordId());
                history.setTitle(title);
                history.setMessage(message);
                history.setSentAt(new Date());
                history.setType("Customer");

                notificationRepository.save(history);
            }

        } catch (Exception e) {
            LOG.error("Error sending customer notification", e);
        }
    }

    //  private static boolean isNotificationSentRecently = false;


    public void sendNotificationAdmin(String title, String message, String userId) {

        //User user = userRepository.findByRecordId(userId);
//        if (isNotificationSentRecently) {
//            LOG.warn("Skipping duplicate admin notification");
//            return;
//        }
//
//        isNotificationSentRecently = true;
//        new java.util.Timer().schedule(new java.util.TimerTask() {
//            @Override
//            public void run() {
//                isNotificationSentRecently = false;
//            }
//        }, 10000);

        try {
            URL url = new URL("https://onesignal.com/api/v1/notifications");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setUseCaches(false);
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            con.setRequestProperty("Authorization", "Basic os_v2_app_q2nk324la5cbhcrprcwrmc5idcn3suexbjpeudn6sjcy2edgccttbjbb2mtdrkf2zwkdeyb7biapjtf6rwj4h3r5put4bx4lpujideq");
            con.setRequestMethod("POST");

            String strJsonBody = String.format("""
                        {
                            "app_id": "869aadeb-8b07-4413-8a2f-88ad160ba818",
                            "include_player_ids": ["%s"],
                            "contents": {"en": "%s"},
                            "headings": {"en": "%s"}
                        }
                    """, userId, message, title);

            byte[] sendBytes = strJsonBody.getBytes(StandardCharsets.UTF_8);
            con.setFixedLengthStreamingMode(sendBytes.length);

            try (OutputStream outputStream = con.getOutputStream()) {
                outputStream.write(sendBytes);
            }

            int httpResponse = con.getResponseCode();
            try (Scanner scanner = new Scanner(
                    httpResponse >= 200 && httpResponse < 400 ? con.getInputStream() : con.getErrorStream(), StandardCharsets.UTF_8)) {
                LOG.debug("Admin Notification Response: {}", scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "");
            }

        } catch (Exception e) {
            LOG.error("Failed to send notification to admin", e);
        }
    }

    public void sendNotificationById(String title, String message, String customerId) {
        try {
            URL url = new URL("https://onesignal.com/api/v1/notifications");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setUseCaches(false);
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            con.setRequestProperty("Authorization", "Basic os_v2_app_jax2fprgdna57alwhbz3bhnksonddgfho5fug2m3xysekqqqjz4gsa356dvjuwpcl35ete6wi75vz7fwjeagwyuaj4ovjjdx6emalty");
            con.setRequestMethod("POST");

            String strJsonBody = "{"
                    + "\"app_id\": \"482fa2be-261b-41df-8176-3873b09daa93\","
                    + "\"include_player_ids\": [\"" + customerId + "\"],"
                    + "\"contents\": {\"en\": \"" + message + "\"},"
                    + "\"headings\": {\"en\": \"" + title + "\"}"
                    + "}";

            byte[] sendBytes = strJsonBody.getBytes(StandardCharsets.UTF_8);
            con.setFixedLengthStreamingMode(sendBytes.length);

            OutputStream outputStream = con.getOutputStream();
            outputStream.write(sendBytes);

            int httpResponse = con.getResponseCode();
            Scanner scanner = new Scanner(
                    httpResponse >= 200 && httpResponse < 400
                            ? con.getInputStream()
                            : con.getErrorStream(),
                    StandardCharsets.UTF_8
            );
            String response = scanner.useDelimiter("\\A").hasNext() ? scanner.next() : "";
            LOG.debug("Notification response: " + response);
            scanner.close();
        } catch (Exception e) {
            LOG.error("Failed to send notification", e);
        }
    }
}
