package kr.iotdoor.boot.service;

import kr.iotdoor.boot.mapper.PortfolioMapper;
import kr.iotdoor.boot.model.portfolio.PortfolioForm;
import kr.iotdoor.boot.model.portfolio.PortfolioItem;
import kr.iotdoor.boot.model.user.AdminUserPrincipal;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

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

@Service
public class PortfolioService {

    private static final String FALLBACK_IMAGE = "/resources/kr/iotdoor/comn/site/layout/image/common/no_img.svg";

    private final PortfolioMapper portfolioMapper;
    private final FileStorageService fileStorageService;

    public PortfolioService(PortfolioMapper portfolioMapper, FileStorageService fileStorageService) {
        this.portfolioMapper = portfolioMapper;
        this.fileStorageService = fileStorageService;
    }

    @Transactional(readOnly = true)
    public List<PortfolioItem> getPortfolioItems() {
        return portfolioMapper.selectPortfolioList().stream()
            .map(this::enrich)
            .toList();
    }

    @Transactional
    public PortfolioItem getPortfolioDetail(String portfolioIdntfNo) {
        if (portfolioMapper.incrementViewCount(portfolioIdntfNo) == 0) {
            return null;
        }

        PortfolioItem item = portfolioMapper.selectPortfolioDetail(portfolioIdntfNo);
        return item == null ? null : enrich(item);
    }

    @Transactional(readOnly = true)
    public List<PortfolioItem> getAdminPortfolioItems() {
        return portfolioMapper.selectPortfolioList().stream()
            .map(this::enrich)
            .toList();
    }

    @Transactional(readOnly = true)
    public PortfolioItem getPortfolioForEdit(String portfolioIdntfNo) {
        PortfolioItem item = portfolioMapper.selectPortfolioDetail(portfolioIdntfNo);
        return item == null ? null : enrich(item);
    }

    @Transactional(readOnly = true)
    public int count() {
        return portfolioMapper.countPortfolio();
    }

    @Transactional
    public void save(PortfolioForm form, MultipartFile thumbnailFile, AdminUserPrincipal principal) {
        String thumbnailAtchFileIdntfNo = form.getThumbnailAtchFileIdntfNo();
        int thumbnailFileSn = 1;

        if (thumbnailFile != null && !thumbnailFile.isEmpty()) {
            thumbnailAtchFileIdntfNo = fileStorageService.storeSingleFile(
                thumbnailFile,
                "portfolio/thumbnail",
                "portfolio-thumbnail"
            ).getAtchFileIdntfNo();
        }

        if (!StringUtils.hasText(thumbnailAtchFileIdntfNo)) {
            throw new IllegalArgumentException("대표 이미지는 필수입니다.");
        }

        if (StringUtils.hasText(form.getPortfolioIdntfNo())) {
            PortfolioItem existing = portfolioMapper.selectPortfolioDetail(form.getPortfolioIdntfNo());
            if (existing == null) {
                throw new IllegalArgumentException("수정할 포트폴리오를 찾을 수 없습니다.");
            }

            existing.setTitle(form.getTitle().trim());
            existing.setContent(form.getContent().trim());
            existing.setThumbnailAtchFileIdntfNo(thumbnailAtchFileIdntfNo);
            existing.setThumbnailFileSn(thumbnailFileSn);
            existing.setUpdatedAt(LocalDateTime.now());
            portfolioMapper.updatePortfolio(existing);
            return;
        }

        PortfolioItem item = new PortfolioItem();
        item.setPortfolioIdntfNo(newIdentifier());
        item.setTitle(form.getTitle().trim());
        item.setContent(form.getContent().trim());
        item.setThumbnailAtchFileIdntfNo(thumbnailAtchFileIdntfNo);
        item.setThumbnailFileSn(thumbnailFileSn);
        item.setRegisteredAt(LocalDateTime.now());
        item.setRegisteredByUserIdntfNo(principal.getUserIdntfNo());
        portfolioMapper.insertPortfolio(item);
    }

    @Transactional
    public void delete(String portfolioIdntfNo) {
        portfolioMapper.deletePortfolio(portfolioIdntfNo);
    }

    @Transactional(readOnly = true)
    public String resolveThumbnailUrl(String atchFileIdntfNo, int fileSn) {
        if (!StringUtils.hasText(atchFileIdntfNo)) {
            return FALLBACK_IMAGE;
        }
        return fileStorageService.toPublicUrl(atchFileIdntfNo, fileSn <= 0 ? 1 : fileSn);
    }

    private PortfolioItem enrich(PortfolioItem item) {
        item.setSummary(summarize(item.getContent()));
        item.setImageUrl(resolveThumbnailUrl(item.getThumbnailAtchFileIdntfNo(), item.getThumbnailFileSn()));
        return item;
    }

    private String summarize(String content) {
        if (!StringUtils.hasText(content)) {
            return "";
        }

        String plainText = content
            .replaceAll("<[^>]*>", " ")
            .replace("&nbsp;", " ")
            .replaceAll("\\s+", " ")
            .trim();

        if (plainText.length() <= 120) {
            return plainText;
        }

        return plainText.substring(0, 120) + "...";
    }

    private String newIdentifier() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
