package com.petshop.backend.service;

import com.petshop.backend.entity.Adoption;
import com.petshop.backend.entity.Appointment;
import com.petshop.backend.entity.Conversation;
import com.petshop.backend.entity.Message;
import com.petshop.backend.entity.Sale;
import com.petshop.backend.entity.SaleItem;
import com.petshop.backend.entity.User;
import com.resend.Resend;
import com.resend.services.emails.model.CreateEmailOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
public class EmailService {

    private static final Logger log = LoggerFactory.getLogger(EmailService.class);
    private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("MMMM d, yyyy");
    private static final DateTimeFormatter TIME_FMT = DateTimeFormatter.ofPattern("h:mm a");

    private final Resend resend;
    private final String from;
    private final String frontendUrl;
    private final ActivityLogService activityLogService;

    public EmailService(
            @Value("${resend.api-key}") String apiKey,
            @Value("${resend.from}") String from,
            @Value("${app.frontend-url}") String frontendUrl,
            ActivityLogService activityLogService) {
        this.resend = new Resend(apiKey);
        this.from = from;
        this.frontendUrl = frontendUrl;
        this.activityLogService = activityLogService;
    }

    public void sendWelcome(User user) {
        if (user.getEmail() == null || user.getEmail().isBlank()) return;
        String subject = "Welcome to PetShop!";
        String html = """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Welcome to PetShop, %s!</h2>
                  <p>Your account has been created successfully.</p>
                  <p>You can now log in and start exploring our pets, products, and services.</p>
                  <p>Thank you for joining us!</p>
                </div>""".formatted(firstName(user));
        send(user.getId(), user.getEmail(), subject, html);
    }

    public void sendPasswordResetLink(User user, String rawToken) {
        if (user.getEmail() == null || user.getEmail().isBlank()) return;
        String link = frontendUrl + "/reset-password?token=" + rawToken;
        String subject = "Reset your PetShop password";
        String html = """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Password Reset Request</h2>
                  <p>Hi %s,</p>
                  <p>We received a request to reset your password. Click the button below to proceed.</p>
                  <p><a href="%s" style="background:#2563eb;color:#fff;padding:10px 20px;border-radius:4px;text-decoration:none;display:inline-block">Reset Password</a></p>
                  <p>This link expires in <strong>30 minutes</strong>. If you did not request a reset, you can safely ignore this email.</p>
                </div>""".formatted(firstName(user), link);
        send(user.getId(), user.getEmail(), subject, html);
    }

    public void sendPurchaseReceipt(Sale sale) {
        User customer = sale.getCustomer();
        if (customer == null || customer.getEmail() == null || customer.getEmail().isBlank()) return;
        String subject = "Your PetShop receipt";
        String html = buildReceiptHtml(sale);
        send(customer.getId(), customer.getEmail(), subject, html);
    }

    public void sendAdoptionConfirmation(Adoption adoption) {
        User customer = adoption.getCustomer();
        if (customer != null && customer.getEmail() != null && !customer.getEmail().isBlank()) {
            String subject = "Your adoption — " + adoption.getPet().getPetName();
            send(customer.getId(), customer.getEmail(), subject, buildAdoptionHtml(adoption, customer));
        }
        User employee = adoption.getEmployee();
        if (employee != null && employee.getEmail() != null && !employee.getEmail().isBlank()) {
            String subject = "Adoption assigned — " + adoption.getPet().getPetName();
            send(employee.getId(), employee.getEmail(), subject, buildAdoptionHtml(adoption, customer));
        }
    }

    public void sendAdoptionReminder(Adoption adoption) {
        User customer = adoption.getCustomer();
        if (customer != null && customer.getEmail() != null && !customer.getEmail().isBlank()) {
            String subject = "Reminder: adoption tomorrow — " + adoption.getPet().getPetName();
            send(customer.getId(), customer.getEmail(), subject, buildAdoptionReminderHtml(adoption));
        }
        User employee = adoption.getEmployee();
        if (employee != null && employee.getEmail() != null && !employee.getEmail().isBlank()) {
            String subject = "Reminder: adoption tomorrow — " + adoption.getPet().getPetName();
            send(employee.getId(), employee.getEmail(), subject, buildAdoptionReminderHtml(adoption));
        }
    }

    public void sendAppointmentConfirmation(Appointment appointment) {
        User customer = appointment.getCustomer();
        if (customer != null && customer.getEmail() != null && !customer.getEmail().isBlank()) {
            String subject = "Appointment confirmed — " + appointment.getService().getServiceName();
            send(customer.getId(), customer.getEmail(), subject, buildAppointmentHtml(appointment));
        }
        User employee = appointment.getEmployee();
        if (employee != null && employee.getEmail() != null && !employee.getEmail().isBlank()) {
            String subject = "Appointment assigned — " + appointment.getService().getServiceName();
            send(employee.getId(), employee.getEmail(), subject, buildAppointmentHtml(appointment));
        }
    }

    public void sendAppointmentReminder(Appointment appointment) {
        User customer = appointment.getCustomer();
        if (customer != null && customer.getEmail() != null && !customer.getEmail().isBlank()) {
            String subject = "Reminder: appointment tomorrow — " + appointment.getService().getServiceName();
            send(customer.getId(), customer.getEmail(), subject, buildAppointmentReminderHtml(appointment));
        }
        User employee = appointment.getEmployee();
        if (employee != null && employee.getEmail() != null && !employee.getEmail().isBlank()) {
            String subject = "Reminder: appointment tomorrow — " + appointment.getService().getServiceName();
            send(employee.getId(), employee.getEmail(), subject, buildAppointmentReminderHtml(appointment));
        }
    }

    public void sendContactMessage(User user, String subject, String body) {
        if (user.getEmail() == null || user.getEmail().isBlank()) return;
        String html = """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Contact form message</h2>
                  <p><strong>From:</strong> %s (%s)</p>
                  <p><strong>Subject:</strong> %s</p>
                  <hr/>
                  <p style="white-space:pre-wrap">%s</p>
                </div>""".formatted(esc(firstName(user)), esc(user.getEmail()), esc(subject), esc(body));
        send(user.getId(), user.getEmail(), "Contact: " + subject, html);
    }

    public void sendChatTranscript(Conversation conversation, List<Message> messages, User customer) {
        if (customer == null || customer.getEmail() == null || customer.getEmail().isBlank()) return;
        String subject = "Your PetShop support transcript";
        String html = buildTranscriptHtml(conversation, messages, customer);
        send(customer.getId(), customer.getEmail(), subject, html);
    }

    private void send(Long recipientUserId, String to, String subject, String html) {
        try {
            CreateEmailOptions options = CreateEmailOptions.builder()
                    .from(from)
                    .to(List.of(to))
                    .subject(subject)
                    .html(html)
                    .build();
            resend.emails().send(options);
            activityLogService.record(recipientUserId, "Sent an email  |  Email sent: " + subject + " → " + to);
        } catch (Exception ex) {
            log.error("Failed to send email '{}' to {}: {}", subject, to, ex.getMessage());
            activityLogService.record(recipientUserId, "Failed to send email  |  Email failed: " + subject + " → " + to);
        }
    }

    private String buildReceiptHtml(Sale sale) {
        StringBuilder rows = new StringBuilder();
        List<SaleItem> items = sale.getItems();
        if (items != null) {
            for (SaleItem item : items) {
                String name = item.getProduct() != null ? item.getProduct().getProdName() : "—";
                rows.append("<tr><td style='padding:6px 8px'>").append(esc(name)).append("</td>")
                    .append("<td style='padding:6px 8px;text-align:center'>").append(item.getQuantity()).append("</td>")
                    .append("<td style='padding:6px 8px;text-align:right'>$").append(fmt(item.getUnitPrice())).append("</td>")
                    .append("<td style='padding:6px 8px;text-align:right'>$").append(fmt(item.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity())))).append("</td></tr>");
            }
        }
        String date = sale.getSaleDate() != null ? sale.getSaleDate().format(DateTimeFormatter.ofPattern("MMMM d, yyyy h:mm a")) : "—";
        return """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Thank you for your purchase!</h2>
                  <p><strong>Date:</strong> %s</p>
                  <p><strong>Payment method:</strong> %s</p>
                  <table style="width:100%%;border-collapse:collapse;margin:16px 0">
                    <thead><tr style="background:#f3f4f6">
                      <th style="padding:6px 8px;text-align:left">Item</th>
                      <th style="padding:6px 8px;text-align:center">Qty</th>
                      <th style="padding:6px 8px;text-align:right">Unit price</th>
                      <th style="padding:6px 8px;text-align:right">Total</th>
                    </tr></thead>
                    <tbody>%s</tbody>
                  </table>
                  <p><strong>Subtotal:</strong> $%s</p>
                  %s
                  %s
                  %s
                  <p style="font-size:1.1em"><strong>Total:</strong> $%s</p>
                  %s
                </div>""".formatted(
                date,
                esc(sale.getPaymentMethod()),
                rows.toString(),
                fmt(sale.getSubtotalAmount()),
                discountLine("Coupon discount", sale.getCouponDiscountAmount()),
                discountLine("Employee discount", sale.getEmployeeDiscountAmount()),
                discountLine("Loyalty discount", sale.getLoyaltyDiscountAmount()),
                fmt(sale.getTotalAmount()),
                sale.getPointsEarned() != null && sale.getPointsEarned() > 0
                        ? "<p>You earned <strong>" + sale.getPointsEarned() + " loyalty points</strong> on this order.</p>"
                        : ""
        );
    }

    private String buildAdoptionHtml(Adoption adoption, User customer) {
        String petName = adoption.getPet() != null ? adoption.getPet().getPetName() : "—";
        String storeName = adoption.getSourceStore() != null ? adoption.getSourceStore().getStoreName() : "—";
        String date = adoption.getAdoptionDate() != null ? adoption.getAdoptionDate().format(DATE_FMT) : "—";
        String customerName = customer != null ? firstName(customer) : "—";
        return """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Adoption update — %s</h2>
                  <p><strong>Customer:</strong> %s</p>
                  <p><strong>Pet:</strong> %s</p>
                  <p><strong>Date:</strong> %s</p>
                  <p><strong>Store:</strong> %s</p>
                  <p><strong>Status:</strong> %s</p>
                </div>""".formatted(esc(petName), esc(customerName), esc(petName), date, esc(storeName), esc(adoption.getAdoptionStatus()));
    }

    private String buildAdoptionReminderHtml(Adoption adoption) {
        String petName = adoption.getPet() != null ? adoption.getPet().getPetName() : "—";
        String storeName = adoption.getSourceStore() != null ? adoption.getSourceStore().getStoreName() : "—";
        String date = adoption.getAdoptionDate() != null ? adoption.getAdoptionDate().format(DATE_FMT) : "—";
        return """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Reminder: adoption tomorrow</h2>
                  <p>This is a reminder that the adoption of <strong>%s</strong> is scheduled for <strong>%s</strong> at <strong>%s</strong>.</p>
                </div>""".formatted(esc(petName), date, esc(storeName));
    }

    private String buildAppointmentHtml(Appointment appointment) {
        String service = appointment.getService() != null ? appointment.getService().getServiceName() : "—";
        String store = appointment.getStore() != null ? appointment.getStore().getStoreName() : "—";
        String date = appointment.getAppointmentDate() != null ? appointment.getAppointmentDate().format(DATE_FMT) : "—";
        String time = appointment.getAppointmentTime() != null ? appointment.getAppointmentTime().format(TIME_FMT) : "—";
        String employee = appointment.getEmployee() != null
                ? appointment.getEmployee().getFirstName() + " " + appointment.getEmployee().getLastName() : "—";
        String pet = appointment.getPet() != null ? appointment.getPet().getPetName() : null;
        return """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Appointment confirmed</h2>
                  <p><strong>Service:</strong> %s</p>
                  <p><strong>Date:</strong> %s</p>
                  <p><strong>Time:</strong> %s</p>
                  <p><strong>Location:</strong> %s</p>
                  <p><strong>Staff:</strong> %s</p>
                  %s
                </div>""".formatted(esc(service), date, time, esc(store), esc(employee),
                pet != null ? "<p><strong>Pet:</strong> " + esc(pet) + "</p>" : "");
    }

    private String buildAppointmentReminderHtml(Appointment appointment) {
        String service = appointment.getService() != null ? appointment.getService().getServiceName() : "—";
        String store = appointment.getStore() != null ? appointment.getStore().getStoreName() : "—";
        String time = appointment.getAppointmentTime() != null ? appointment.getAppointmentTime().format(TIME_FMT) : "—";
        return """
                <div style="font-family:sans-serif;max-width:600px;margin:auto">
                  <h2>Reminder: appointment tomorrow</h2>
                  <p>Your <strong>%s</strong> appointment is scheduled for tomorrow at <strong>%s</strong> at <strong>%s</strong>.</p>
                </div>""".formatted(esc(service), time, esc(store));
    }

    private String buildTranscriptHtml(Conversation conversation, List<Message> messages, User customer) {
        StringBuilder rows = new StringBuilder();
        for (Message msg : messages) {
            String sender = msg.getSenderId() != null && msg.getSenderId().equals(customer.getId())
                    ? firstName(customer) : "Support";
            String ts = msg.getTimestamp() != null
                    ? msg.getTimestamp().format(DateTimeFormatter.ofPattern("MMM d, h:mm a")) : "";
            String content = msg.getContent() != null ? esc(msg.getContent()) : "";
            rows.append("<tr><td style='padding:6px 8px;white-space:nowrap'>").append(ts).append("</td>")
                .append("<td style='padding:6px 8px;white-space:nowrap'>").append(esc(sender)).append("</td>")
                .append("<td style='padding:6px 8px'>").append(content).append("</td></tr>");
        }
        return """
                <div style="font-family:sans-serif;max-width:700px;margin:auto">
                  <h2>Support chat transcript</h2>
                  <p>Hi %s, here is the transcript of your support conversation.</p>
                  <table style="width:100%%;border-collapse:collapse;margin:16px 0;font-size:0.9em">
                    <thead><tr style="background:#f3f4f6">
                      <th style="padding:6px 8px;text-align:left">Time</th>
                      <th style="padding:6px 8px;text-align:left">Sender</th>
                      <th style="padding:6px 8px;text-align:left">Message</th>
                    </tr></thead>
                    <tbody>%s</tbody>
                  </table>
                </div>""".formatted(firstName(customer), rows.toString());
    }

    private String firstName(User user) {
        if (user.getFirstName() != null && !user.getFirstName().isBlank()) return esc(user.getFirstName());
        if (user.getFullName() != null && !user.getFullName().isBlank()) return esc(user.getFullName().split("\\s+")[0]);
        return esc(user.getUsername());
    }

    private String fmt(BigDecimal value) {
        return value != null ? String.format("%.2f", value) : "0.00";
    }

    private String discountLine(String label, BigDecimal value) {
        if (value == null || value.compareTo(BigDecimal.ZERO) == 0) return "";
        return "<p><strong>" + label + ":</strong> -$" + fmt(value) + "</p>";
    }

    private String esc(String s) {
        if (s == null) return "";
        return s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;");
    }
}
