package com.writeoff.module.system.service;

import com.writeoff.common.exception.BusinessException;
import com.writeoff.module.system.dto.CreatePlatformDictionaryItemRequest;
import com.writeoff.module.system.dto.CreatePlatformDictionaryTypeRequest;
import com.writeoff.module.system.dto.UpdatePlatformDictionaryItemRequest;
import com.writeoff.module.system.model.PlatformDictionaryItem;
import com.writeoff.module.system.model.PlatformDictionaryType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

@Service
public class PlatformDictionaryService {
    private final JdbcTemplate jdbcTemplate;

    private static final RowMapper<PlatformDictionaryItem> ITEM_ROW_MAPPER = (rs, n) -> new PlatformDictionaryItem(
            rs.getLong("id"),
            rs.getString("dict_type"),
            rs.getString("dict_code"),
            rs.getString("dict_name"),
            rs.getInt("sort_no"),
            rs.getString("status"),
            rs.getString("remark")
    );
    private static final RowMapper<PlatformDictionaryType> TYPE_ROW_MAPPER = (rs, n) -> new PlatformDictionaryType(
            rs.getLong("id"),
            rs.getString("dict_type"),
            rs.getString("dict_name"),
            rs.getInt("sort_no"),
            rs.getString("status"),
            rs.getString("remark")
    );
    private static final Pattern DICT_TYPE_PATTERN = Pattern.compile("^[A-Z][A-Z0-9_]{1,63}$");

    public PlatformDictionaryService(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<PlatformDictionaryItem> list(String dictType, Boolean enabledOnly) {
        StringBuilder sql = new StringBuilder(
                "SELECT id, dict_type, dict_code, dict_name, sort_no, status, remark " +
                        "FROM platform_dictionary_item WHERE is_deleted=0"
        );
        if (dictType != null && !dictType.trim().isEmpty()) {
            sql.append(" AND dict_type='").append(dictType.trim().replace("'", "''")).append("'");
        }
        if (Boolean.TRUE.equals(enabledOnly)) {
            sql.append(" AND status='ENABLED'");
        }
        sql.append(" ORDER BY dict_type ASC, sort_no ASC, id ASC");
        return jdbcTemplate.query(sql.toString(), ITEM_ROW_MAPPER);
    }

    public List<PlatformDictionaryType> listTypes(Boolean enabledOnly) {
        StringBuilder sql = new StringBuilder(
                "SELECT id, dict_type, dict_name, sort_no, status, remark " +
                        "FROM platform_dictionary_type WHERE is_deleted=0"
        );
        if (Boolean.TRUE.equals(enabledOnly)) {
            sql.append(" AND status='ENABLED'");
        }
        sql.append(" ORDER BY sort_no ASC, id ASC");
        return jdbcTemplate.query(sql.toString(), TYPE_ROW_MAPPER);
    }

    public PlatformDictionaryType createType(CreatePlatformDictionaryTypeRequest request) {
        String dictType = normalizeDictType(request.getDictType());
        Integer dup = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM platform_dictionary_type WHERE dict_type=? AND is_deleted=0",
                Integer.class,
                dictType
        );
        if (dup != null && dup > 0) {
            throw new BusinessException(10001, "字典类型已存在");
        }
        jdbcTemplate.update(
                "INSERT INTO platform_dictionary_type (dict_type, dict_name, sort_no, status, remark, created_by, updated_by) " +
                        "VALUES (?, ?, ?, 'ENABLED', ?, 0, 0)",
                dictType,
                request.getDictName().trim(),
                request.getSortNo(),
                request.getRemark()
        );
        Long id = jdbcTemplate.queryForObject("SELECT IFNULL(MAX(id), 0) FROM platform_dictionary_type", Long.class);
        return findTypeById(id == null ? 0L : id);
    }

    public PlatformDictionaryItem create(CreatePlatformDictionaryItemRequest request) {
        String dictType = normalizeDictType(request.getDictType());
        assertTypeExists(dictType);
        String dictCode = normalizeDictCode(request.getDictCode());
        Integer dup = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM platform_dictionary_item WHERE dict_type=? AND dict_code=? AND is_deleted=0",
                Integer.class,
                dictType,
                dictCode
        );
        if (dup != null && dup > 0) {
            throw new BusinessException(10001, "字典编码已存在");
        }
        jdbcTemplate.update(
                "INSERT INTO platform_dictionary_item (dict_type, dict_code, dict_name, sort_no, status, remark, created_by, updated_by) " +
                        "VALUES (?, ?, ?, ?, 'ENABLED', ?, 0, 0)",
                dictType,
                dictCode,
                request.getDictName().trim(),
                request.getSortNo(),
                request.getRemark()
        );
        Long id = jdbcTemplate.queryForObject("SELECT IFNULL(MAX(id), 0) FROM platform_dictionary_item", Long.class);
        return findById(id == null ? 0L : id);
    }

    public PlatformDictionaryItem update(Long id, UpdatePlatformDictionaryItemRequest request) {
        assertExists(id);
        String status = normalizeStatus(request.getStatus());
        jdbcTemplate.update(
                "UPDATE platform_dictionary_item SET dict_name=?, sort_no=?, remark=?, status=?, updated_at=CURRENT_TIMESTAMP WHERE id=?",
                request.getDictName().trim(),
                request.getSortNo(),
                request.getRemark(),
                status,
                id
        );
        return findById(id);
    }

    public void enable(Long id) {
        assertExists(id);
        jdbcTemplate.update("UPDATE platform_dictionary_item SET status='ENABLED', updated_at=CURRENT_TIMESTAMP WHERE id=?", id);
    }

    public void disable(Long id) {
        assertExists(id);
        jdbcTemplate.update("UPDATE platform_dictionary_item SET status='DISABLED', updated_at=CURRENT_TIMESTAMP WHERE id=?", id);
    }

    private PlatformDictionaryItem findById(Long id) {
        List<PlatformDictionaryItem> list = jdbcTemplate.query(
                "SELECT id, dict_type, dict_code, dict_name, sort_no, status, remark FROM platform_dictionary_item WHERE id=? AND is_deleted=0",
                ITEM_ROW_MAPPER,
                id
        );
        if (list.isEmpty()) {
            throw new BusinessException(10003, "字典项不存在");
        }
        return list.get(0);
    }

    private void assertExists(Long id) {
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM platform_dictionary_item WHERE id=? AND is_deleted=0",
                Integer.class,
                id
        );
        if (count == null || count == 0) {
            throw new BusinessException(10003, "字典项不存在");
        }
    }

    private String normalizeDictType(String value) {
        String val = value == null ? "" : value.trim().toUpperCase();
        if (!DICT_TYPE_PATTERN.matcher(val).matches()) {
            throw new BusinessException(10001, "字典类型编码格式非法，仅支持大写字母/数字/下划线，且需以字母开头");
        }
        return val;
    }

    private String normalizeDictCode(String value) {
        String val = value == null ? "" : value.trim().toUpperCase();
        if (val.isEmpty()) {
            throw new BusinessException(10001, "字典编码不能为空");
        }
        return val;
    }

    private String normalizeStatus(String value) {
        String val = value == null ? "" : value.trim().toUpperCase();
        if (!"ENABLED".equals(val) && !"DISABLED".equals(val)) {
            throw new BusinessException(10001, "状态必须为 ENABLED 或 DISABLED");
        }
        return val;
    }

    private PlatformDictionaryType findTypeById(Long id) {
        List<PlatformDictionaryType> list = jdbcTemplate.query(
                "SELECT id, dict_type, dict_name, sort_no, status, remark FROM platform_dictionary_type WHERE id=? AND is_deleted=0",
                TYPE_ROW_MAPPER,
                id
        );
        if (list.isEmpty()) {
            throw new BusinessException(10003, "字典类型不存在");
        }
        return list.get(0);
    }

    public PlatformDictionaryItem findEnabledItemByName(String dictType, String dictName) {
        String type = dictType == null ? "" : dictType.trim().toUpperCase(Locale.ROOT);
        String name = dictName == null ? "" : dictName.trim();
        if (type.isEmpty() || name.isEmpty()) {
            return null;
        }
        List<PlatformDictionaryItem> list = jdbcTemplate.query(
                "SELECT id, dict_type, dict_code, dict_name, sort_no, status, remark " +
                        "FROM platform_dictionary_item WHERE dict_type=? AND dict_name=? AND status='ENABLED' AND is_deleted=0 LIMIT 1",
                ITEM_ROW_MAPPER,
                type,
                name
        );
        return list.isEmpty() ? null : list.get(0);
    }

    public PlatformDictionaryItem createEnabledItem(String dictType, String dictName, String dictCodePrefix, String remark) {
        String type = normalizeDictType(dictType);
        String name = dictName == null ? "" : dictName.trim();
        if (name.isEmpty()) {
            throw new BusinessException(10001, "????????");
        }
        PlatformDictionaryItem existing = findEnabledItemByName(type, name);
        if (existing != null) {
            return existing;
        }
        assertTypeExists(type);
        String basePrefix = dictCodePrefix == null || dictCodePrefix.trim().isEmpty()
                ? type
                : dictCodePrefix.trim().toUpperCase(Locale.ROOT);
        String code = basePrefix;
        int suffix = 1;
        while (existsDictCode(type, code)) {
            code = basePrefix + "_" + suffix;
            suffix += 1;
        }
        CreatePlatformDictionaryItemRequest request = new CreatePlatformDictionaryItemRequest();
        request.setDictType(type);
        request.setDictCode(code);
        request.setDictName(name);
        request.setSortNo(9999);
        request.setRemark(remark);
        return create(request);
    }

    private boolean existsDictCode(String dictType, String dictCode) {
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM platform_dictionary_item WHERE dict_type=? AND dict_code=? AND is_deleted=0",
                Integer.class,
                dictType,
                dictCode
        );
        return count != null && count > 0;
    }

    private void assertTypeExists(String dictType) {
        Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM platform_dictionary_type WHERE dict_type=? AND is_deleted=0",
                Integer.class,
                dictType
        );
        if (count == null || count == 0) {
            throw new BusinessException(10003, "字典类型不存在，请先新增字典类型");
        }
    }
}
