package com.zioinfo.cms.banner;

import com.zioinfo.cms.banner.mapper.BannerMapper;
import com.zioinfo.cms.common.ApiResponse;
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. 노출 스케줄(startAt~endAt) + active 기반 현재 노출 조회.
 */
@RestController
@RequestMapping("/api/cms/banner")
@RequiredArgsConstructor
public class BannerController {

    private final BannerMapper mapper;

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

    /** 현재 노출 대상(active + 스케줄 유효). */
    @GetMapping("/active")
    public ApiResponse<List<CmsBanner>> active(@RequestParam(required = false) String position) {
        return ApiResponse.ok(mapper.findActiveNow(position));
    }

    @GetMapping("/{id}")
    public ApiResponse<CmsBanner> get(@PathVariable Long id) {
        CmsBanner b = mapper.findById(id);
        if (b == null) throw new RuntimeException("ERR-CMS-BANNER-404: 배너 없음");
        return ApiResponse.ok(b);
    }

    @PostMapping
    public ApiResponse<CmsBanner> create(@RequestBody Map<String, Object> req, Authentication auth) {
        CmsBanner b = bind(new CmsBanner(), req);
        b.setCreatedBy(auth != null ? auth.getName() : "system");
        mapper.insert(b);
        return ApiResponse.ok(mapper.findById(b.getId()));
    }

    @PutMapping("/{id}")
    public ApiResponse<CmsBanner> update(@PathVariable Long id, @RequestBody Map<String, Object> req) {
        CmsBanner b = mapper.findById(id);
        if (b == null) throw new RuntimeException("ERR-CMS-BANNER-404: 배너 없음");
        bind(b, req);
        mapper.update(b);
        return ApiResponse.ok(mapper.findById(id));
    }

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

    private CmsBanner bind(CmsBanner b, Map<String, Object> r) {
        if (r.containsKey("name")) b.setName(str(r.get("name")));
        if (r.containsKey("bannerType")) b.setBannerType(str(r.get("bannerType")));
        if (r.containsKey("imageUrl")) b.setImageUrl(str(r.get("imageUrl")));
        if (r.containsKey("linkUrl")) b.setLinkUrl(str(r.get("linkUrl")));
        if (r.containsKey("position")) b.setPosition(str(r.get("position")));
        if (r.containsKey("targetRule")) b.setTargetRule(jsonStr(r.get("targetRule")));
        if (r.containsKey("sortOrder")) b.setSortOrder(intOf(r.get("sortOrder")));
        if (r.containsKey("active")) b.setActive(Boolean.parseBoolean(String.valueOf(r.get("active"))));
        if (r.containsKey("startAt")) b.setStartAt(dt(r.get("startAt")));
        if (r.containsKey("endAt")) b.setEndAt(dt(r.get("endAt")));
        if (b.getBannerType() == null) b.setBannerType("PROMOTION");
        return b;
    }

    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 null; } }
    private LocalDateTime dt(Object o) { if (o == null || String.valueOf(o).isBlank()) return null; try { return LocalDateTime.parse(String.valueOf(o)); } catch (Exception e) { return null; } }
    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); }
    }
}
