package com.pharmacopoeia.service;

import com.pharmacopoeia.dto.DrugDetailResponse;
import com.pharmacopoeia.repository.DrugRepository;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DrugService {

    private final DrugRepository drugRepository;

    public DrugService(DrugRepository drugRepository) {
        this.drugRepository = drugRepository;
    }

    public DrugDetailResponse getDrugDetail(String drugId) {
        return drugRepository.findByDrugId(drugId)
                .map(d -> DrugDetailResponse.builder()
                        .id(d.getId())
                        .drugId(d.getDrugId())
                        .name(d.getName())
                        .nameEn(d.getNameEn())
                        .pinyin(d.getPinyin())
                        .category(d.getCategory())
                        .subcategory(d.getSubcategory())
                        .approvalNumber(d.getApprovalNumber())
                        .sections(d.getSections())
                        .sourceVersion(d.getSourceVersion())
                        .sourceVolume(d.getSourceVolume())
                        .sourcePage(d.getSourcePage())
                        .isActive(d.getIsActive())
                        .createdAt(d.getCreatedAt())
                        .updatedAt(d.getUpdatedAt())
                        .build())
                .orElse(null);
    }

    public Map<String, Object> searchDrugs(String keyword, String category, int page, int pageSize) {
        var pageable = PageRequest.of(page - 1, pageSize);
        var result = (keyword != null && !keyword.isBlank())
                ? drugRepository.searchByKeyword(keyword, pageable)
                : (category != null && !category.isBlank())
                        ? drugRepository.findByCategoryAndIsActiveTrue(category, pageable)
                        : drugRepository.findByIsActiveTrue(pageable);

        var items = result.getContent().stream()
                .map(d -> {
                    Map<String, Object> m = new java.util.LinkedHashMap<>();
                    m.put("drug_id", d.getDrugId());
                    m.put("name", d.getName());
                    m.put("name_en", d.getNameEn() != null ? d.getNameEn() : "");
                    m.put("pinyin", d.getPinyin() != null ? d.getPinyin() : "");
                    m.put("category", d.getCategory() != null ? d.getCategory() : "");
                    m.put("subcategory", d.getSubcategory() != null ? d.getSubcategory() : "");
                    m.put("source_version", d.getSourceVersion() != null ? d.getSourceVersion() : "");
                    m.put("source_volume", d.getSourceVolume() != null ? d.getSourceVolume() : "");
                    m.put("source_page", d.getSourcePage() != null ? d.getSourcePage() : "");
                    m.put("is_active", d.getIsActive());
                    return m;
                })
                .collect(Collectors.toList());

        return Map.of(
                "items", items,
                "total", result.getTotalElements(),
                "page", page,
                "page_size", pageSize,
                "total_pages", result.getTotalPages()
        );
    }

    public List<Map<String, Object>> getCategoryTree() {
        // 返回层次化分类树（与 Python 一致的格式）
        List<Object[]> pairs = drugRepository.findCategorySubcategoryPairs();
        Map<String, List<String>> tree = new java.util.LinkedHashMap<>();
        for (Object[] row : pairs) {
            String cat = (String) row[0];
            String sub = (String) row[1];
            tree.computeIfAbsent(cat, k -> new java.util.ArrayList<>());
            if (sub != null && !sub.isBlank() && !tree.get(cat).contains(sub)) {
                tree.get(cat).add(sub);
            }
        }
        return tree.entrySet().stream()
                .map(e -> Map.<String, Object>of("name", e.getKey(), "children", e.getValue()))
                .collect(Collectors.toList());
    }
}
