package incheon.cmm.g2f.basemap.web;

import incheon.cmm.g2f.basemap.service.G2FBasemapService;
import incheon.cmm.g2f.basemap.vo.G2FBasemapVO;
import incheon.com.cmm.api.DefaultApiResponse;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Valid;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

@Controller
@RequestMapping("/cmm/g2f/basemap")
public class G2FBasemapController {
    private static final Logger log = LoggerFactory.getLogger(G2FBasemapController.class);
    
    private final G2FBasemapService basemapService;

    public G2FBasemapController(G2FBasemapService basemapService) {
        this.basemapService = basemapService;
    }

    @GetMapping("/basemapList.do")
    public String list(Model model,
                       @RequestParam(value = "page", defaultValue = "1") int page,
                       @ModelAttribute G2FBasemapVO vo) {
        // 페이지 인덱스 설정
        vo.setPageIndex(page);

        // PaginationInfo 객체 생성 (전자정부 표준)
        PaginationInfo paginationInfo = new PaginationInfo();
        paginationInfo.setCurrentPageNo(page);
        paginationInfo.setRecordCountPerPage(vo.getRecordCountPerPage());
        paginationInfo.setPageSize(vo.getPageSize());

        // 페이징 인덱스 설정
        vo.setFirstIndex(paginationInfo.getFirstRecordIndex());
        vo.setLastIndex(paginationInfo.getLastRecordIndex());
        vo.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());

        // 전체 개수 조회
        int totalCount = basemapService.getTotalCount(vo.getSearchKeyword());
        paginationInfo.setTotalRecordCount(totalCount);

        // 목록 조회
        List<G2FBasemapVO> list = basemapService.getList(vo.getSearchKeyword(), page, vo.getRecordCountPerPage());

        // 썸네일 데이터 생성
        HashMap<String, String> thumbnail = new HashMap<>();
        for (G2FBasemapVO baseMap : list) {
            thumbnail.put(baseMap.getBcrnLyrId(), "background: url(" + baseMap.getThmbUrl().replaceAll("\\r?\\n", "), url(") + "); background-repeat: no-repeat; background-size: cover;");
        }

        // Model에 데이터 추가
        model.addAttribute("list", list);
        model.addAttribute("totalCount", totalCount);
        model.addAttribute("paginationInfo", paginationInfo);
        model.addAttribute("searchVO", vo);
        model.addAttribute("thumbnail", thumbnail);

        return "cmm/g2f/basemap/list";
    }

    @GetMapping("/create.do")
    public String showCreateForm(Model model) {
        model.addAttribute("basemap", new G2FBasemapVO());
        return "cmm/g2f/basemap/create";
    }

    @PostMapping("/create")
    public String create(@Valid @ModelAttribute("basemap") G2FBasemapVO basemap,
                         BindingResult bindingResult,
                         Model model) {
        if (bindingResult.hasErrors()) {
            return "cmm/g2f/basemap/create";
        }
        
        try {
            // iconuseEn이 true면 저작권 앞에 © 기호 추가
            if (Boolean.TRUE.equals(basemap.getIconuseEn()) && basemap.getCprgtCn() != null) {
                basemap.setCprgtCn("© " + basemap.getCprgtCn());
            }
            
            basemap.setCrtId("admin");
            basemapService.create(basemap);
            
            model.addAttribute("message", "배경지도가 등록되었습니다.");
            model.addAttribute("messageType", "success");
            model.addAttribute("redirectUrl", "/cmm/g2f/basemap/basemapList.do");
            
            log.info("배경지도 등록 성공: {}", basemap.getBcrnLyrId());
        } catch (DataAccessException e) {
            log.error("배경지도 등록 실패: {}", basemap.getBcrnLyrId(), e);
            
            model.addAttribute("message", "배경지도 등록에 실패했습니다.");
            model.addAttribute("messageType", "error");
        }
        
        return "cmm/g2f/basemap/create";
    }

    @GetMapping("/edit.do")
    public String editForm(@RequestParam("bcrnLyrId") String bcrnLyrId, Model model) {
        G2FBasemapVO basemap = basemapService.getById(bcrnLyrId);
        
        // cprgtCn이 "&copy; "로 시작하면 iconuseEn을 true로 설정하고 "&copy; " 제거
        if (basemap.getCprgtCn() != null && basemap.getCprgtCn().startsWith("&copy; ")) {
            basemap.setIconuseEn(true);
            basemap.setCprgtCn(basemap.getCprgtCn().substring(7)); // "&copy; " 제거 (7글자)
        } else {
            basemap.setIconuseEn(false);
        }
        
        model.addAttribute("basemap", basemap);
        return "cmm/g2f/basemap/edit";
    }

    @PostMapping("/edit")
    public String edit(@RequestParam("bcrnLyrId") String bcrnLyrId,
                       @Valid @ModelAttribute("basemap") G2FBasemapVO basemap,
                       BindingResult bindingResult,
                       Model model) {
        if (bindingResult.hasErrors()) {
            model.addAttribute("basemap", basemap);
            return "cmm/g2f/basemap/edit";
        }
        
        try {
            basemap.setBcrnLyrId(bcrnLyrId);
            basemap.setChgId("admin");
            
            // cprgtCn은 이미 JSP에서 처리되어 전달됨
            basemapService.update(basemap);
            
            model.addAttribute("message", "배경지도가 수정되었습니다.");
            model.addAttribute("messageType", "success");
            model.addAttribute("redirectUrl", "/cmm/g2f/basemap/basemapList.do");
            
            log.info("배경지도 수정 성공: {}", bcrnLyrId);
        } catch (DataAccessException e) {
            log.error("배경지도 수정 실패: {}", bcrnLyrId, e);
            
            model.addAttribute("message", "배경지도 수정에 실패했습니다.");
            model.addAttribute("messageType", "error");
        }
        
        return "cmm/g2f/basemap/edit";
    }

    @PostMapping("/delete")
    public String delete(@RequestParam("bcrnLyrId") String bcrnLyrId,
                        RedirectAttributes redirectAttributes) {
        try {
            basemapService.delete(bcrnLyrId);
            
            redirectAttributes.addFlashAttribute("message", "배경지도가 삭제되었습니다.");
            redirectAttributes.addFlashAttribute("messageType", "success");
            
            log.info("배경지도 삭제 성공: {}", bcrnLyrId);
        } catch (DataAccessException e) {
            log.error("배경지도 삭제 실패: {}", bcrnLyrId, e);
            
            redirectAttributes.addFlashAttribute("message", "배경지도 삭제에 실패했습니다.");
            redirectAttributes.addFlashAttribute("messageType", "error");
        }
        
        return "redirect:/cmm/g2f/basemap/basemapList.do";
    }

    // REST API
    @GetMapping(value = "/api/v1/basemaps", produces = "application/json")
    @ResponseBody
    public ResponseEntity<DefaultApiResponse<List<G2FBasemapVO>>> basemaps() throws IOException {
        return ResponseEntity.ok(DefaultApiResponse.success(basemapService.getList()));
    }
}