package com.zioinfo.cms.seo;

import com.zioinfo.cms.ai.AiService;
import com.zioinfo.cms.common.ApiResponse;
import com.zioinfo.cms.seo.mapper.SeoMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * SEO API — 메타데이터/OG/canonical, 리다이렉트, robots.txt, AI SEO 제안.
 */
@RestController
@RequestMapping("/api/cms/seo")
@RequiredArgsConstructor
public class SeoController {

    private final SeoMapper mapper;
    private final AiService aiService;

    // ── 메타데이터 ──
    @GetMapping("/meta")
    public ApiResponse<List<CmsSeoMeta>> listMeta() {
        return ApiResponse.ok(mapper.findAllMeta());
    }

    @GetMapping("/meta/by-path")
    public ApiResponse<CmsSeoMeta> byPath(@RequestParam String pathKey,
                                          @RequestParam(defaultValue = "ko") String locale) {
        return ApiResponse.ok(mapper.findMetaByPath(pathKey, locale));
    }

    @PostMapping("/meta")
    public ApiResponse<CmsSeoMeta> createMeta(@RequestBody Map<String, Object> req) {
        CmsSeoMeta m = bind(new CmsSeoMeta(), req);
        mapper.insertMeta(m);
        return ApiResponse.ok(mapper.findMetaById(m.getId()));
    }

    @PutMapping("/meta/{id}")
    public ApiResponse<CmsSeoMeta> updateMeta(@PathVariable Long id, @RequestBody Map<String, Object> req) {
        CmsSeoMeta m = mapper.findMetaById(id);
        if (m == null) throw new RuntimeException("ERR-CMS-SEO-404: 메타 없음");
        bind(m, req);
        mapper.updateMeta(m);
        return ApiResponse.ok(mapper.findMetaById(id));
    }

    @DeleteMapping("/meta/{id}")
    public ApiResponse<Void> deleteMeta(@PathVariable Long id) {
        mapper.deleteMeta(id);
        return ApiResponse.ok(null);
    }

    // ── 리다이렉트 ──
    @GetMapping("/redirect")
    public ApiResponse<List<CmsRedirect>> listRedirects() {
        return ApiResponse.ok(mapper.findAllRedirects());
    }

    @PostMapping("/redirect")
    public ApiResponse<CmsRedirect> createRedirect(@RequestBody Map<String, Object> req) {
        CmsRedirect r = new CmsRedirect();
        r.setFromPath(str(req.get("fromPath")));
        r.setToPath(str(req.get("toPath")));
        r.setStatusCode(req.get("statusCode") == null ? 301 : intOf(req.get("statusCode")));
        r.setActive(req.get("active") == null || Boolean.parseBoolean(String.valueOf(req.get("active"))));
        mapper.insertRedirect(r);
        return ApiResponse.ok(r);
    }

    @DeleteMapping("/redirect/{id}")
    public ApiResponse<Void> deleteRedirect(@PathVariable Long id) {
        mapper.deleteRedirect(id);
        return ApiResponse.ok(null);
    }

    /** robots.txt 생성. */
    @GetMapping("/robots")
    public ApiResponse<Map<String, String>> robots(@RequestParam(defaultValue = "https://cms.zioinfo.co.kr") String baseUrl) {
        String txt = "User-agent: *\nAllow: /\nSitemap: " + baseUrl.replaceAll("/+$", "") + "/sitemap.xml\n";
        return ApiResponse.ok(Map.of("robots", txt));
    }

    /** AI SEO 제안 (메타·키워드·가독성). */
    @PostMapping("/ai-suggest")
    public ApiResponse<Map<String, Object>> aiSuggest(@RequestBody Map<String, String> req) {
        return ApiResponse.ok(aiService.seoSuggest(req.get("title"), req.get("body")));
    }

    private CmsSeoMeta bind(CmsSeoMeta m, Map<String, Object> r) {
        if (r.containsKey("pathKey")) m.setPathKey(str(r.get("pathKey")));
        if (r.containsKey("title")) m.setTitle(str(r.get("title")));
        if (r.containsKey("description")) m.setDescription(str(r.get("description")));
        if (r.containsKey("keywords")) m.setKeywords(str(r.get("keywords")));
        if (r.containsKey("ogTitle")) m.setOgTitle(str(r.get("ogTitle")));
        if (r.containsKey("ogImage")) m.setOgImage(str(r.get("ogImage")));
        if (r.containsKey("canonical")) m.setCanonical(str(r.get("canonical")));
        if (r.containsKey("locale")) m.setLocale(str(r.get("locale")));
        if (m.getLocale() == null) m.setLocale("ko");
        return m;
    }

    private String str(Object o) { return o == null ? null : String.valueOf(o); }
    private Integer intOf(Object o) { if (o == null) return null; try { return Integer.valueOf(String.valueOf(o).trim()); } catch (Exception e) { return 301; } }
}
