package com.example.demo.common;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class FinanceService {

    private static final String PARAM_KEY = "finance.categories";

    private final SystemParameterRepository systemParameterRepository;
    private final FinanceDefaultsProperties financeDefaultsProperties;
    private final javax.sql.DataSource dataSource;
    private final AppDefaultsProperties appDefaults;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public FinanceService(SystemParameterRepository systemParameterRepository, FinanceDefaultsProperties financeDefaultsProperties, javax.sql.DataSource dataSource, AppDefaultsProperties appDefaults) {
        this.systemParameterRepository = systemParameterRepository;
        this.financeDefaultsProperties = financeDefaultsProperties;
        this.dataSource = dataSource;
        this.appDefaults = appDefaults;
    }

    public Map<String, Object> getCategories(Long shopId) {
        Map<String, Object> body = new HashMap<>();
        // 0) 优先从 finance_categories 表读取（避免中文乱码/统一排序）
        List<Map<String, String>> income = queryCategoriesFromTable(shopId, "income");
        List<Map<String, String>> expense = queryCategoriesFromTable(shopId, "expense");

        // 1) 回落读取 system_parameters
        try {
            if (income == null || income.isEmpty() || expense == null || expense.isEmpty()) {
                Optional<SystemParameter> opt = systemParameterRepository.findByShopIdAndKey(shopId, PARAM_KEY);
                if (opt.isPresent()) {
                    String json = opt.get().getValue();
                    if (json != null && !json.isBlank()) {
                        JsonNode root = objectMapper.readTree(json);
                        if (income == null || income.isEmpty()) {
                            JsonNode incNode = root.get("income");
                            if (incNode != null && incNode.isArray()) {
                                income = objectMapper.convertValue(incNode, new TypeReference<List<Map<String,String>>>(){});
                            }
                        }
                        if (expense == null || expense.isEmpty()) {
                            JsonNode expNode = root.get("expense");
                            if (expNode != null && expNode.isArray()) {
                                expense = objectMapper.convertValue(expNode, new TypeReference<List<Map<String,String>>>(){});
                            }
                        }
                    }
                }
            }
        } catch (Exception ignored) {
            // 忽略异常，回落至默认配置
        }

        // 2) 回落：应用配置 app.finance.*
        if (income == null || income.isEmpty()) {
            income = parsePairs(financeDefaultsProperties.getIncomeCategories());
        }
        if (expense == null || expense.isEmpty()) {
            expense = parsePairs(financeDefaultsProperties.getExpenseCategories());
        }

        body.put("incomeCategories", income);
        body.put("expenseCategories", expense);
        return body;
    }

    private List<Map<String, String>> parsePairs(String pairs) {
        if (pairs == null || pairs.isBlank()) return Collections.emptyList();
        return Arrays.stream(pairs.split(","))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .map(s -> {
                    int idx = s.indexOf(":");
                    String key = idx > 0 ? s.substring(0, idx).trim() : s.trim();
                    String label = idx > 0 ? s.substring(idx + 1).trim() : key;
                    Map<String, String> m = new HashMap<>();
                    m.put("key", key);
                    m.put("label", label);
                    return m;
                })
                .collect(Collectors.toList());
    }

    private List<Map<String, String>> queryCategoriesFromTable(Long shopId, String type) {
        Long fallbackShopId = appDefaults == null ? 1L : (appDefaults.getShopId() == null ? 1L : appDefaults.getShopId());
        try (java.sql.Connection c = dataSource.getConnection();
             java.sql.PreparedStatement ps = c.prepareStatement(
                     "SELECT shop_id, `key`, label FROM finance_categories WHERE shop_id IN (?, ?) AND type=? AND status=1 " +
                             "ORDER BY CASE WHEN shop_id=? THEN 0 ELSE 1 END, sort_order, id")) {
            ps.setLong(1, shopId);
            ps.setLong(2, fallbackShopId);
            ps.setString(3, type);
            ps.setLong(4, shopId);
            try (java.sql.ResultSet rs = ps.executeQuery()) {
                java.util.Map<String,String> firstByKey = new java.util.LinkedHashMap<>();
                while (rs.next()) {
                    String key = rs.getString(2);
                    String label = rs.getString(3);
                    if (!firstByKey.containsKey(key)) {
                        firstByKey.put(key, label);
                    }
                }
                java.util.List<java.util.Map<String,String>> list = new java.util.ArrayList<>();
                for (java.util.Map.Entry<String,String> e : firstByKey.entrySet()) {
                    java.util.Map<String,String> m = new java.util.HashMap<>();
                    m.put("key", e.getKey());
                    m.put("label", e.getValue());
                    list.add(m);
                }
                return list;
            }
        } catch (Exception ignored) {
            return java.util.Collections.emptyList();
        }
    }
}


