package com.zioinfo.cms.product;

import com.zioinfo.cms.admin.AuditService;
import com.zioinfo.cms.ai.AiService;
import com.zioinfo.cms.common.ApiResponse;
import com.zioinfo.cms.integration.OcrClient;
import com.zioinfo.cms.product.mapper.ProductContentMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 상품 콘텐츠/상세빌더 API.
 *
 * <p>AI 상품설명 초안 + OCR 문서→상품정보 추출 보조. Mall은 delivery로 published 소비.
 */
@RestController
@RequestMapping("/api/cms/product")
@RequiredArgsConstructor
public class ProductController {

    private final ProductContentMapper mapper;
    private final AiService aiService;
    private final OcrClient ocrClient;
    private final AuditService auditService;

    @GetMapping
    public ApiResponse<List<CmsProductContent>> list(@RequestParam(required = false) String status,
                                                     @RequestParam(required = false) String keyword) {
        return ApiResponse.ok(mapper.findAll(status, keyword));
    }

    @GetMapping("/{id}")
    public ApiResponse<CmsProductContent> get(@PathVariable Long id) {
        CmsProductContent p = mapper.findById(id);
        if (p == null) throw new RuntimeException("ERR-CMS-PRODUCT-404: 상품 콘텐츠 없음");
        return ApiResponse.ok(p);
    }

    @PostMapping
    public ApiResponse<CmsProductContent> create(@RequestBody Map<String, Object> req, Authentication auth) {
        CmsProductContent p = bind(new CmsProductContent(), req);
        p.setStatus("DRAFT");
        p.setCreatedBy(auth != null ? auth.getName() : "system");
        mapper.insert(p);
        auditService.log("PRODUCT_CREATE", p.getProductName(), "mallId=" + p.getMallProductId());
        return ApiResponse.ok(mapper.findById(p.getId()));
    }

    @PutMapping("/{id}")
    public ApiResponse<CmsProductContent> update(@PathVariable Long id, @RequestBody Map<String, Object> req) {
        CmsProductContent p = mapper.findById(id);
        if (p == null) throw new RuntimeException("ERR-CMS-PRODUCT-404: 상품 콘텐츠 없음");
        bind(p, req);
        mapper.update(p);
        return ApiResponse.ok(mapper.findById(id));
    }

    /** 발행. */
    @PostMapping("/{id}/publish")
    public ApiResponse<CmsProductContent> publish(@PathVariable Long id) {
        if (mapper.findById(id) == null) throw new RuntimeException("ERR-CMS-PRODUCT-404: 상품 콘텐츠 없음");
        mapper.updateStatus(id, "PUBLISHED");
        auditService.log("PRODUCT_PUBLISH", String.valueOf(id), null);
        return ApiResponse.ok(mapper.findById(id));
    }

    /** AI 상품 설명 초안. */
    @PostMapping("/ai-draft")
    public ApiResponse<Map<String, String>> aiDraft(@RequestBody Map<String, String> req) {
        return ApiResponse.ok(Map.of("draft", aiService.draft("product", req.get("topic"), req.get("tone"))));
    }

    /** OCR 문서→상품정보 추출 보조. */
    @GetMapping("/ocr-extract/{documentId}")
    public ApiResponse<Map<String, Object>> ocrExtract(@PathVariable String documentId) {
        return ApiResponse.ok(ocrClient.getExtraction(documentId));
    }

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

    private CmsProductContent bind(CmsProductContent p, Map<String, Object> r) {
        if (r.containsKey("mallProductId")) p.setMallProductId(str(r.get("mallProductId")));
        if (r.containsKey("productName")) p.setProductName(str(r.get("productName")));
        if (r.containsKey("summary")) p.setSummary(str(r.get("summary")));
        if (r.containsKey("detailBlocks")) p.setDetailBlocks(jsonStr(r.get("detailBlocks")));
        if (r.containsKey("specs")) p.setSpecs(jsonStr(r.get("specs")));
        if (r.containsKey("locale")) p.setLocale(str(r.get("locale")));
        if (p.getLocale() == null) p.setLocale("ko");
        return p;
    }

    private String str(Object o) { return o == null ? null : String.valueOf(o); }
    private String jsonStr(Object o) {
        if (o == null) return null;
        if (o instanceof String s) return s;
        try { return new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(o); } catch (Exception e) { return String.valueOf(o); }
    }
}
