using System.Text;
using Microsoft.AspNetCore.Mvc;
using economy.Controllers.Price.Global;

namespace economy.Controllers
{
    // sitemap.xml 생성
    //
    // 기존에는 wwwroot/sitemap.xml 정적 파일을 외부 생성기로 만들어 두었는데,
    // 같은 페이지의 쿼리스트링 변형(페이지네이션 41개, 조회기간/코드 파라미터 등)이 대부분을 차지해
    // 98건 중 실제 고유 페이지는 20여 개뿐이었고 lastmod 도 2025-08-10 에 고정되어 있었다.
    // 여기서는 정규 URL 만 내보낸다.
    public class SitemapController : Controller
    {
        // 리버스 프록시 뒤에서는 Request.Scheme 이 http 로 들어올 수 있어 설정값을 우선 사용한다.
        private const string DefaultBaseUrl = "https://economy.web.or.kr";

        // 파라미터가 없는 정규 경로만 담는다.
        // 제외 대상:
        //  - Business/Search, Whois/Search : [HttpPost] 전용이라 GET 은 405
        //  - Home/Error                    : 오류 페이지
        //  - Price/Domestic/Item/Detail/{item} : 품목 코드가 외부 API 응답에서 오므로 목록을 고정할 수 없다.
        //                                        Item/List 페이지의 링크를 통해 크롤링된다.
        private static readonly string[] StaticPaths =
        {
            "/",
            "/Home/Privacy",
            "/Business/Number",
            "/Days/Anniversary",
            "/Days/Holiday",
            "/Days/Seasonal",
            "/Days/Sundry",
            "/FIFA",
            "/Financial/Exchange",
            "/Financial/Interest",
            "/Financial/International",
            "/Lotto",
            "/Whois",
            "/Price/Domestic/Emission",
            "/Price/Domestic/Flower",
            "/Price/Domestic/Gold",
            "/Price/Domestic/Oil",
            "/Price/Domestic/Item/List.cshtml",
            "/Price/Global/NaturalGas"
        };

        private readonly IConfiguration _configuration;

        public SitemapController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpGet("/sitemap.xml")]
        [HttpHead("/sitemap.xml")]
        [ResponseCache(Duration = 3600, Location = ResponseCacheLocation.Any)]
        public IActionResult Index()
        {
            var baseUrl = (_configuration["Site:BaseUrl"] ?? DefaultBaseUrl).TrimEnd('/');

            // 시세 페이지는 매일 갱신되므로 날짜 단위로만 표기한다.
            var today = DateTime.UtcNow.ToString("yyyy-MM-dd");

            var builder = new StringBuilder();
            builder.AppendLine(@"<?xml version=""1.0"" encoding=""UTF-8""?>");
            builder.AppendLine(@"<urlset xmlns=""http://www.sitemaps.org/schemas/sitemap/0.9"">");

            foreach (var path in StaticPaths)
            {
                AppendUrl(builder, baseUrl + path, today, "daily", path == "/" ? "1.0" : "0.8");
            }

            // 국제 원자재 시세. 품목 목록은 GlobalController.CommodityMap 을 그대로 읽어
            // 라우트가 실제로 처리하는 값과 어긋나지 않게 한다.
            foreach (var commodity in GlobalController.CommodityMap.Keys.OrderBy(key => key, StringComparer.OrdinalIgnoreCase))
            {
                AppendUrl(builder, $"{baseUrl}/Price/Global/{commodity}", today, "daily", "0.8");
            }

            builder.AppendLine("</urlset>");

            return Content(builder.ToString(), "application/xml", Encoding.UTF8);
        }

        private static void AppendUrl(StringBuilder builder, string location, string lastModified, string changeFrequency, string priority)
        {
            builder.AppendLine("  <url>");
            builder.AppendLine($"    <loc>{location}</loc>");
            builder.AppendLine($"    <lastmod>{lastModified}</lastmod>");
            builder.AppendLine($"    <changefreq>{changeFrequency}</changefreq>");
            builder.AppendLine($"    <priority>{priority}</priority>");
            builder.AppendLine("  </url>");
        }
    }
}
