package com.dora.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * SPA前端应用Fallback控制器
 * 处理所有未匹配的前端路由请求，返回index.html
 * 
 * 注意：此Controller作为WebConfig资源处理的备选方案
 * 通常情况下WebConfig中的资源处理已经足够，此Controller仅供特殊需求使用
 * 
 * @author dora
 * @date 2024/12/01
 */
@Slf4j
@Controller
@Tag(name = "SPA前端", description = "单页应用前端路由支持")
public class SpaFallbackController {

    /**
     * 处理根路径请求
     * 专门处理根路径的GET请求，返回index.html
     */
    @GetMapping("/")
    @Operation(summary = "前端应用首页", description = "返回前端应用的index.html文件")
    public ResponseEntity<String> index(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        String referer = request.getHeader("Referer");
        
        log.info("根路径Controller处理 - User-Agent: {}, Referer: {}", 
            userAgent != null && userAgent.length() > 50 ? userAgent.substring(0, 50) + "..." : userAgent,
            referer);
        
        try {
            Resource indexHtml = new ClassPathResource("/static/index.html");
            if (indexHtml.exists() && indexHtml.isReadable()) {
                String content = indexHtml.getContentAsString(StandardCharsets.UTF_8);
                return ResponseEntity.ok()
                    .contentType(MediaType.TEXT_HTML)
                    .body(content);
            } else {
                log.warn("index.html文件不存在或无法读取");
                return ResponseEntity.status(503) // Service Unavailable
                    .contentType(MediaType.TEXT_HTML)
                    .body("<!DOCTYPE html><html><head><title>应用启动中...</title></head><body><h1>应用启动中，请稍候...</h1></body></html>");
            }
        } catch (IOException e) {
            log.error("读取index.html失败", e);
            return ResponseEntity.status(500) // Internal Server Error
                .contentType(MediaType.TEXT_HTML)
                .body("<!DOCTYPE html><html><head><title>加载失败</title></head><body><h1>页面加载失败，请刷新重试</h1></body></html>");
        }
    }

    /**
     * 通用SPA路由fallback处理
     * 处理所有前端路由请求（非API请求），都返回index.html
     * 
     * 注意：此方法的RequestMapping需要非常小心，避免拦截API请求
     * 建议优先使用WebConfig中的资源处理配置
     */
    @RequestMapping("/{path:[^\\.]*}")
    @Operation(summary = "SPA路由fallback", description = "处理前端路由请求，返回index.html")
    public ResponseEntity<String> spaFallback(@PathVariable String path, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String userAgent = request.getHeader("User-Agent");
        
        // 安全检查：排除API请求路径
        if (requestURI.startsWith("/user/") || 
            requestURI.startsWith("/admin/") || 
            requestURI.startsWith("/api/") ||
            requestURI.startsWith("/swagger-ui/") ||
            requestURI.startsWith("/v3/api-docs/") ||
            requestURI.startsWith("/webjars/") ||
            requestURI.startsWith("/static/") ||
            requestURI.contains(".")) {
            
            log.debug("跳过SPA fallback处理API路径: {}", requestURI);
            return ResponseEntity.notFound().build();
        }
        
        log.info("SPA fallback处理前端路由: {} - User-Agent: {}", 
            requestURI,
            userAgent != null && userAgent.length() > 50 ? userAgent.substring(0, 50) + "..." : userAgent);
        
        try {
            Resource indexHtml = new ClassPathResource("/static/index.html");
            if (indexHtml.exists() && indexHtml.isReadable()) {
                String content = indexHtml.getContentAsString(StandardCharsets.UTF_8);
                return ResponseEntity.ok()
                    .contentType(MediaType.TEXT_HTML)
                    .body(content);
            } else {
                log.warn("index.html文件不存在或无法读取");
                return ResponseEntity.status(503) // Service Unavailable
                    .contentType(MediaType.TEXT_HTML)
                    .body("<!DOCTYPE html><html><head><title>应用启动中...</title></head><body><h1>应用启动中，请稍候...</h1></body></html>");
            }
        } catch (IOException e) {
            log.error("读取index.html失败", e);
            return ResponseEntity.status(500) // Internal Server Error
                .contentType(MediaType.TEXT_HTML)
                .body("<!DOCTYPE html><html><head><title>加载失败</title></head><body><h1>页面加载失败，请刷新重试</h1></body></html>");
        }
    }
}
