package com.mosquito.project.service;

import com.mosquito.project.config.PosterConfig;
import com.mosquito.project.domain.Activity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.imageio.ImageIO;

@Service
public class PosterRenderService {

    private static final Logger log = LoggerFactory.getLogger(PosterRenderService.class);

    private final PosterConfig posterConfig;
    private final ShortLinkService shortLinkService;
    private final Map<String, Image> imageCache = new ConcurrentHashMap<>();

    public PosterRenderService(PosterConfig posterConfig, ShortLinkService shortLinkService) {
        this.posterConfig = posterConfig;
        this.shortLinkService = shortLinkService;
    }

    public byte[] renderPoster(Long activityId, Long userId, String templateName) {
        PosterConfig.PosterTemplate template = posterConfig.getTemplate(templateName);
        if (template == null) {
            template = posterConfig.getTemplate(posterConfig.getDefaultTemplate());
        }

        Activity activity = null;
        try {
            // 获取活动信息
            // activity = activityService.getActivityById(activityId);
        } catch (Exception e) {
            log.debug("Could not load activity: {}", e.getMessage());
        }

        BufferedImage image = new BufferedImage(template.getWidth(), template.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        try {
            // 绘制背景
            if (template.getBackground() != null && !template.getBackground().isBlank()) {
                Image bgImage = loadImage(template.getBackground());
                if (bgImage != null) {
                    g.drawImage(bgImage, 0, 0, template.getWidth(), template.getHeight(), null);
                } else {
                    g.setColor(Color.decode(template.getBackgroundColor()));
                    g.fillRect(0, 0, template.getWidth(), template.getHeight());
                }
            } else {
                g.setColor(Color.decode(template.getBackgroundColor()));
                g.fillRect(0, 0, template.getWidth(), template.getHeight());
            }

            // 绘制元素
            for (Map.Entry<String, PosterConfig.PosterElement> entry : template.getElements().entrySet()) {
                PosterConfig.PosterElement element = entry.getValue();
                drawElement(g, element, activity, activityId, userId);
            }

        } finally {
            g.dispose();
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "PNG", baos);
            return baos.toByteArray();
        } catch (Exception e) {
            log.error("Failed to generate poster image", e);
            throw new RuntimeException("Failed to generate poster", e);
        }
    }

    public String renderPosterHtml(Long activityId, Long userId, String templateName) {
        PosterConfig.PosterTemplate template = posterConfig.getTemplate(templateName);
        if (template == null) {
            template = posterConfig.getTemplate(posterConfig.getDefaultTemplate());
        }

        Activity activity = null;
        try {
            // activity = activityService.getActivityById(activityId);
        } catch (Exception e) {
            log.debug("Could not load activity: {}", e.getMessage());
        }

        String shortUrl = "/r/" + shortLinkService.create(
            "https://example.com/landing?activityId=" + activityId + "&inviter=" + userId
        ).getCode();

        StringBuilder html = new StringBuilder();
        html.append("<!DOCTYPE html>");
        html.append("<html><head>");
        html.append("<meta charset=\"UTF-8\">");
        html.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
        html.append("<title>").append(activity != null ? escapeHtml(activity.getName()) : "分享").append("</title>");
        html.append("<style>");
        html.append("body { margin: 0; padding: 0; background: ").append(template.getBackgroundColor()).append("; }");
        html.append(".poster { position: relative; width: ").append(template.getWidth()).append("px; margin: 0 auto; }");
        if (template.getBackground() != null) {
            html.append(".poster { background-image: url('").append(template.getBackground()).append("'); background-size: cover; }");
        }
        html.append("</style></head><body>");
        html.append("<div class=\"poster\" style=\"width: ").append(template.getWidth()).append("px; height: ").append(template.getHeight()).append("px;\">");

        for (Map.Entry<String, PosterConfig.PosterElement> entry : template.getElements().entrySet()) {
            PosterConfig.PosterElement element = entry.getValue();
            String content = resolveContent(element, activity, activityId, userId, shortUrl);

            if ("text".equals(element.getType())) {
                html.append("<div style=\"position: absolute; left: ").append(element.getX()).append("px; top: ").append(element.getY()).append("px;");
                html.append(" width: ").append(element.getWidth()).append("px; height: ").append(element.getHeight()).append("px;");
                html.append(" color: ").append(element.getColor()).append("; font-size: ").append(element.getFontSize()).append(";");
                html.append(" font-family: ").append(element.getFontFamily()).append("; text-align: ").append(element.getTextAlign()).append(";");
                html.append(" overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\">");
                html.append(content);
                html.append("</div>");
            } else if ("qrcode".equals(element.getType())) {
                String encodedUrl;
                try {
                    encodedUrl = java.net.URLEncoder.encode(shortUrl, java.nio.charset.StandardCharsets.UTF_8);
                } catch (Exception e) {
                    encodedUrl = shortUrl;
                }
                html.append("<div style=\"position: absolute; left: ").append(element.getX()).append("px; top: ").append(element.getY()).append("px;");
                html.append(" width: ").append(element.getWidth()).append("px; height: ").append(element.getHeight()).append("px;");
                html.append(" background: #fff; padding: 10px;\">");
                html.append("<img src=\"https://api.qrserver.com/v1/create-qr-code/?size=").append(element.getWidth() - 20).append("x").append(element.getHeight() - 20);
                html.append("&data=").append(encodedUrl).append("\" style=\"width: 100%; height: 100%;\">");
                html.append("</div>");
            } else if ("image".equals(element.getType())) {
                html.append("<img src=\"").append(content).append("\" style=\"position: absolute; left: ").append(element.getX()).append("px; top: ").append(element.getY());
                html.append("px; width: ").append(element.getWidth()).append("px; height: ").append(element.getHeight()).append("px;\">");
            } else if ("button".equals(element.getType())) {
                html.append("<a href=\"").append(shortUrl).append("\" style=\"position: absolute; left: ").append(element.getX()).append("px; top: ").append(element.getY());
                html.append("px; width: ").append(element.getWidth()).append("px; height: ").append(element.getHeight()).append("px; display: block;");
                if (element.getBackground() != null) {
                    html.append(" background: ").append(element.getBackground()).append(";");
                }
                html.append(" border-radius: ").append(element.getBorderRadius() != null ? element.getBorderRadius() : "0").append(";\">");
                html.append("<span style=\"display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: ").append(element.getColor()).append("; font-size: ").append(element.getFontSize()).append(";\">");
                html.append(content);
                html.append("</span></a>");
            }
        }

        html.append("</div></body></html>");
        return html.toString();
    }

    private void drawElement(Graphics2D g, PosterConfig.PosterElement element, Activity activity, Long activityId, Long userId) {
        String content = resolveContent(element, activity, activityId, userId, "/r/abc123");

        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        if ("text".equals(element.getType())) {
            g.setColor(Color.decode(element.getColor()));
            Font font = new Font(element.getFontFamily(), Font.BOLD, parseFontSize(element.getFontSize()));
            g.setFont(font);
            FontMetrics fm = g.getFontMetrics();
            int textY = element.getY() + fm.getAscent();
            g.drawString(content, element.getX(), textY);
        } else if ("qrcode".equals(element.getType())) {
            g.setColor(Color.WHITE);
            g.fillRect(element.getX(), element.getY(), element.getWidth(), element.getHeight());
        } else if ("rect".equals(element.getType())) {
            g.setColor(Color.decode(element.getBackground() != null ? element.getBackground() : "#ffffff"));
            g.fillRect(element.getX(), element.getY(), element.getWidth(), element.getHeight());
        }
    }

    private String resolveContent(PosterConfig.PosterElement element, Activity activity, Long activityId, Long userId, String shortUrl) {
        String raw = element.getContent();
        if (raw == null) return "";

        return raw.replace("{{activityName}}", activity != null ? activity.getName() : "活动")
                  .replace("{{activityId}}", String.valueOf(activityId))
                  .replace("{{userId}}", String.valueOf(userId))
                  .replace("{{shortUrl}}", shortUrl)
                  .replace("{{title}}", element.getContent());
    }

    private Image loadImage(String urlStr) {
        return imageCache.computeIfAbsent(urlStr, k -> {
            try {
                URL url = new URL(posterConfig.getCdnBaseUrl() + "/" + urlStr);
                return ImageIO.read(url);
            } catch (Exception e) {
                log.debug("Failed to load image: {}", urlStr);
                return null;
            }
        });
    }

    private int parseFontSize(String size) {
        try {
            return Integer.parseInt(size.replace("px", ""));
        } catch (Exception e) {
            return 16;
        }
    }

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