package com.ruoyi.app.omgpay;

import com.ruoyi.app.omgpay.dto.OmgNotifyRequest;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.system.omgpay.service.OmgIpnAuditService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;

/** Browser-facing OMG return endpoints; payment state remains owned by notify/query processing. */
@RestController
@RequestMapping("/pay/omg")
public class OmgPaymentReturnController {
    private static final Logger log = LoggerFactory.getLogger(OmgPaymentReturnController.class);
    private static final Resource UNI_APP_BRIDGE =
            new ClassPathResource("static/omg/uni.webview.1.5.8.js");
    private final OmgPaymentClientReturnService service;
    private final OmgIpnAuditService ipnAuditService;

    public OmgPaymentReturnController(OmgPaymentClientReturnService service,
                                      OmgIpnAuditService ipnAuditService) {
        this.service = service;
        this.ipnAuditService = ipnAuditService;
    }

    @Anonymous
    @PostMapping(value = "/result", produces = MediaType.TEXT_HTML_VALUE)
    public ResponseEntity<String> result(@OmgNotifyForm OmgNotifyRequest request) {
        log.info("OMG client payment result received ip={}, rawForm={}",
                sourceIp(request), rawForm(request));
        appendAudit(request);
        return html(service.paymentResult(request));
    }

    @Anonymous
    @GetMapping(value = "/bridge.js", produces = "application/javascript;charset=UTF-8")
    public ResponseEntity<Resource> bridge() {
        return ResponseEntity.ok()
                .contentType(new MediaType("application", "javascript", StandardCharsets.UTF_8))
                .header(HttpHeaders.CACHE_CONTROL, "no-store")
                .header("X-Content-Type-Options", "nosniff")
                .body(UNI_APP_BRIDGE);
    }

    private static String sourceIp(OmgNotifyRequest request) {
        return request == null ? "unknown" : request.getSourceIp();
    }

    private static String rawForm(OmgNotifyRequest request) {
        return request == null ? "" : request.getRawForm();
    }

    private void appendAudit(OmgNotifyRequest request) {
        try {
            ipnAuditService.append(sourceIp(request), rawForm(request));
        } catch (Exception auditError) {
            log.error("OMG client return IPN append failed ip={}, rawForm={}",
                    sourceIp(request), rawForm(request), auditError);
        }
    }

    private static ResponseEntity<String> html(OmgPaymentReturnPage page) {
        return ResponseEntity.status(page.statusCode())
                .contentType(new MediaType("text", "html", StandardCharsets.UTF_8))
                .header(HttpHeaders.CACHE_CONTROL, "no-store")
                .header("Pragma", "no-cache")
                .header("Referrer-Policy", "no-referrer")
                .header("X-Content-Type-Options", "nosniff")
                .header("Content-Security-Policy",
                        "default-src 'none'; style-src 'unsafe-inline'; script-src 'self' 'unsafe-inline'; base-uri 'none'; form-action 'none'")
                .body(page.html());
    }
}
