package com.caliverse.admin.domain.datacomponent;


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

import com.caliverse.admin.domain.entity.metaEnum.EJoinInProgressType;
import com.caliverse.admin.domain.entity.metaEnum.ETeamAssignmentType;
import com.caliverse.admin.domain.entity.metadata.*;
import com.caliverse.admin.global.common.exception.MetaDataException;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.caliverse.admin.domain.entity.EMetaData;

import static com.caliverse.admin.global.common.utils.DataHelper.parseDateTime;
import static com.caliverse.admin.global.common.utils.DataHelper.parseFloat;

@Component
@Slf4j
public class MetaDataFileLoader {
    private final JsonFileReader jsonFileReader;
    private final Map<Integer, MetaItemData> items;
    private final Map<String, MetaTextStringData> textStrings;
    private final Map<Integer, MetaClothTypeData> clothTypes;
    private final Map<Integer, MetaToolData> toolItems;
    private final Map<Integer, String> banWords;
    private final Map<MetaQuestKey, MetaQuestData> quests;
    private final Map<Integer, MetaBuildingData> buildings;
    private final Map<Integer, MetaLandData> lands;
    private final Map<Integer, MetaGameModeData> gameModes;
    private final Map<Integer, MetaGameFFAConfigData> gameFFAConfigs;
    private final Map<Integer, MetaBattleConfigData> battleConfigs;
    private final Map<Integer, MetaBattleRewardData> battleRewards;
    private final Map<String, MetaSystemMailData> systemMails;
    private final Map<Integer, MetaGameModeMatchData> gameModeMatches;
    private final List<MetaBuffData> buffs;
    private final List<MetaGachaData> gachas;
    private final List<MetaItemSetData> itemSets;
    private final List<MetaAttributeRandomGroupData> attributeRandomGroups;
    private final List<MetaWebLinkData> webLinks;
    private final List<MetaBrandData> brands;
    private final List<MetaCraftingData> craftings;
    private final List<MetaCurrencyData> currencies;
    private final List<MetaRankingData> rankings;
    private final List<MetaEventActionScoreData> eventActionScoreDatas;

    public MetaDataFileLoader(JsonFileReader jsonFileReader) {
        this.jsonFileReader = jsonFileReader;
        this.gameModes = new ConcurrentHashMap<>();
        this.items = new ConcurrentHashMap<>();
        this.textStrings = new ConcurrentHashMap<>();
        this.clothTypes = new ConcurrentHashMap<>();
        this.toolItems = new ConcurrentHashMap<>();
        this.banWords = new ConcurrentHashMap<>();
        this.quests = new ConcurrentHashMap<>();
        this.buildings = new ConcurrentHashMap<>();
        this.lands = new ConcurrentHashMap<>();
        this.battleConfigs = new ConcurrentHashMap<>();
        this.battleRewards = new ConcurrentHashMap<>();
        this.systemMails = new ConcurrentHashMap<>();
        this.gameFFAConfigs = new ConcurrentHashMap<>();
        this.gameModeMatches = new ConcurrentHashMap<>();
        this.buffs = new ArrayList<>();
        this.gachas = new ArrayList<>();
        this.itemSets = new ArrayList<>();
        this.attributeRandomGroups = new ArrayList<>();
        this.webLinks = new ArrayList<>();
        this.brands = new ArrayList<>();
        this.craftings = new ArrayList<>();
        this.currencies = new ArrayList<>();
        this.rankings = new ArrayList<>();
        this.eventActionScoreDatas = new ArrayList<>();
    }

    @PostConstruct
    public void initialize(){
        loadMetaData();
    }

    @Scheduled(fixedDelayString = "${caliverse.metadata.reload.interval}")
    public void reloadMetaData() {
        try {
            log.info("Starting metadata reload");
            loadMetaData();
            log.info("Metadata reload completed");
        } catch (Exception e) {
            log.error("Failed to reload metadata", e);
        }
    }

    private void loadMetaData(){
        try{
            loadTextStrings();
            loadQuests();
            loadLand();
            loadBanWord();
            loadBuilding();
            loadItems();
            loadToolItems();
            loadClothType();
            loadBattleConfig();
            loadBattleReward();
            loadSystemMail();
            loadGameMode();
            loadGameModeFFAConfig();
            loadGameModeMatch();
            loadBuff();
            loadBrand();
            loadAttributeRandomGroup();
            loadGacha();
            loadItemSet();
            loadWebLinkLocalize();
            loadCrafting();
            loadCurrency();
            loadRanking();
            loadEventActionScore();
        }catch(MetaDataException e){
            log.error("Failed to initialize metadata", e);
            throw e;
        }
    }

    public Optional<MetaTextStringData> getName(String text){
        if(text == null) return Optional.empty();

        return Optional.ofNullable(textStrings.get(text));
    }

    //아이템 가져오기
    public Optional<MetaItemData> getMetaItem(int itemId) {
        if(itemId == 0) return Optional.empty();

        return Optional.ofNullable(items.get(itemId));
    }

    public List<MetaItemData> getMetaItems() {
        return new ArrayList<>(items.values());
    }

    //의상 타입 가져오기
    public Optional<MetaClothTypeData> getMetaClothType(int id) {
        if(id == 0) return Optional.empty();

        return Optional.ofNullable(clothTypes.get(id));
    }

    //도구 정보 가져오기
    public Optional<MetaToolData> getMetaToolItem(int id) {
        if(id == 0) return Optional.empty();

        return Optional.ofNullable(toolItems.get(id));
    }

    //퀘스트 정보 가져오기
    public List<MetaQuestData> getMetaQuests(int id) {
        if(id == 0) return Collections.emptyList();

        return quests.entrySet().stream()
                .filter(entry -> entry.getKey().getQeustId().equals(id))
                .map(Map.Entry::getValue)
                .collect(Collectors.toList());
    }

    //빌딩 정보 가져오기
    public Optional<MetaBuildingData> getMetaBuildingItem(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return Optional.ofNullable(buildings.get(id));
    }

    public List<MetaBuildingData> getMetaBuildings() {
        return new ArrayList<>(buildings.values());
    }

    //랜드 정보 가져오기
    public Optional<MetaLandData> getMetaLandItem(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return Optional.ofNullable(lands.get(id));
    }

    public Optional<MetaGachaData> getMetaGacha(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return gachas.stream().filter(data -> data.getId() == id).findFirst();
    }

    public Optional<MetaItemSetData> getMetaItemSet(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return itemSets.stream().filter(data -> data.getId() == id).findFirst();
    }

    public Optional<MetaCraftingData> getMetaCrafting(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return craftings.stream().filter(data -> data.getId() == id).findFirst();
    }

    public Optional<MetaAttributeRandomGroupData> getMetaAttributeRandomGroup(String groupId) {
        if(groupId.isEmpty()){
            return Optional.empty();
        }

        return attributeRandomGroups.stream().filter(data -> data.getGroupId().equals(groupId)).findFirst();
    }

    public Optional<MetaAttributeRandomGroupData> getMetaAttributeRandomGroup(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return attributeRandomGroups.stream().filter(data -> data.getKey() == id).findFirst();
    }

    public Optional<MetaBuffData> getMetaBuff(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return buffs.stream().filter(data -> data.getBuffId() == id).findFirst();
    }

    public Optional<MetaBrandData> getMetaBrand(int id) {
        if(id == 0){
            return Optional.empty();
        }

        return brands.stream().filter(data -> data.getId() == id).findFirst();
    }

    public Optional<MetaWebLinkData> getMetaWebLinkLocalize(String key) {
        if(key.isEmpty()) {
            return Optional.empty();
        }

        return webLinks.stream().filter(data -> data.getKey().equals(key)).findFirst();
    }

    public Optional<MetaCurrencyData> getMetaCurrency(int id) {
        if(id == 0) {
            return Optional.empty();
        }

        return currencies.stream().filter(data -> data.getId() == id).findFirst();
    }

    public Optional<MetaRankingData> getMetaRanking(int id) {
        if(id == 0) {
            return Optional.empty();
        }

        return rankings.stream().filter(data -> data.getId() == id).findFirst();
    }

    //////////////// 리스트 조회
    public List<MetaLandData> getMetaLands() {
        return new ArrayList<>(lands.values());
    }

    public List<MetaGameModeData> getMetaGameModes() {
        return new ArrayList<>(gameModes.values());
    }

    public List<MetaGameFFAConfigData> getMetaGameFFAConfigs() {
        return new ArrayList<>(gameFFAConfigs.values());
    }

    public List<MetaGameModeMatchData> getMetaGameModeMatchs() {
        return new ArrayList<>(gameModeMatches.values());
    }

    // 추후 없어질것
    public List<MetaBattleConfigData> getMetaBattleConfigs() {
        return new ArrayList<>(battleConfigs.values());
    }
    // 추후 없어질것
    public List<MetaBattleRewardData> getMetaBattleRewards() {
        return battleRewards.values().stream()
                .collect(Collectors.groupingBy(MetaBattleRewardData::getGroupID))  // groupId로 그룹화
                .values().stream()                                                 // 그룹화된 리스트들의 스트림
                .map(group -> group.get(0))                                       // 각 그룹의 첫 번째 항목만 선택
                .sorted(Comparator.comparing(MetaBattleRewardData::getGroupID))   // groupId 기준으로 정렬
                .collect(Collectors.toList());
    }

    public List<MetaSystemMailData> getMetaSystemMail() {
        return new ArrayList<>(systemMails.values());
    }

    public List<MetaBrandData> getMetaBrand() {
        return brands;
    }

    public List<MetaRankingData> getMetaRanking() {
        return rankings;
    }

    public List<MetaEventActionScoreData> getMetaEventActionScore() {
        return eventActionScoreDatas.stream()
                .collect(Collectors.groupingBy(MetaEventActionScoreData::getGroupId))  // groupId로 그룹화
                .values().stream()
                .map(group -> group.get(0))
                .sorted(Comparator.comparing(MetaEventActionScoreData::getGroupId))   // groupId 기준으로 정렬
                .collect(Collectors.toList());
    }

    public List<MetaCraftingData> getMetaCrafting() {
        return craftings;
    }






    // 문자 데이터 로드
    private void loadTextStrings() {
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.TEXT_STRING_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("textStrings data is empty or file not found: {}", EMetaData.TOOL_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaTextStringData textString = new MetaTextStringData();
            textString.setKey((String) meta.get("Key"));
            textString.setKor((String) meta.get("SourceString"));
            textString.setEn((String) meta.get("en"));
            textString.setJa((String) meta.get("ja"));
            textStrings.put(textString.getKey(), textString);
        });

        log.info("loadTextStrings {} Load Complete",EMetaData.TEXT_STRING_DATA.getFileName());
    }

    // 아이템 정보 데이터 로드
    public void loadItems(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.ITEM_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("item data is empty or file not found: {}", EMetaData.TOOL_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaItemData item = new MetaItemData();

            // 기본 정보
            item.setItemId((Integer) meta.get("item_id"));
            item.setName((String) meta.get("name"));
            item.setDesc((String) meta.get("desc"));
            item.setGender((String) meta.get("gender"));

            // 이미지 정보
            item.setImage3dDp((String) meta.get("image_3D_DP"));
            item.setImage3dDpOpacity((String) meta.get("image_3D_DP_opacity"));
            item.setImage3d((String) meta.get("image_3D"));
            item.setImage3dOpacity((String) meta.get("image_3D_opacity"));
            item.setImage2d((String) meta.get("image_2D"));

            // 출시 정보
            item.setReleaseDate(parseDateTime(meta.get("release_date")));
            item.setBrand((Integer) meta.get("Brand"));
            item.setIsNft((Boolean) meta.get("isNFT"));

            // 타입 정보
            item.setLargeType((String) meta.get("type_large"));
            item.setSmallType((String) meta.get("type_small"));
            item.setRegisterId((Integer) meta.get("register_id"));

            // 수량 정보
            item.setMaxCount((Integer) meta.get("max_count"));
            item.setStackMaxCount((Integer) meta.get("stack_max_count"));

            // 만료 정보
            item.setExpireType((String) meta.get("expire_type"));
            item.setExpireFixedTermStart(parseDateTime(meta.get("expire_fixedTerm_start")));
            item.setExpireFixedTermEnd(parseDateTime(meta.get("expire_fixedTerm_end")));
            item.setExpireTimeSec((Integer) meta.get("expire_time_sec"));

            // 거래 정보
            item.setIsUserTradable((Boolean) meta.get("is_user_tradable"));
            item.setIsSystemTradable((Boolean) meta.get("is_system_tradable"));
            item.setSellPriceType((String) meta.get("sell_price_type"));
            item.setSellId((Integer) meta.get("sell_id"));
            item.setSellPrice((Integer) meta.get("sell_price"));

            // UI 관련
            item.setOrder((Integer) meta.get("order"));
            item.setIsThrowable((Boolean) meta.get("is_throwable"));

            // 액션 정보
            item.setActionType((String) meta.get("ActionType"));
            item.setActionValue((Integer) meta.get("ActionValue"));

            // 디테일 뷰 정보
            item.setDetailOffset(parseFloat(meta.get("DetailOffset")));
            item.setDetailScale(parseFloat(meta.get("DetailScale")));
            item.setGuidePopup((Integer) meta.get("GuidePopup"));
            item.setDetailRoll(parseFloat(meta.get("DetailRoll")));
            item.setDetailPitch(parseFloat(meta.get("DetailPitch")));
            item.setDetailCameraRight(parseFloat(meta.get("DetailCameraRight")));
            item.setDetailCameraHeight(parseFloat(meta.get("DetailCameraHeight")));
            item.setDetailCameraAngle(parseFloat(meta.get("DetailCameraAngle")));

            // 속성 정보
            item.setRarity((String) meta.get("Rarity"));
            item.setDefaultAttribute((String) meta.get("DefaultAttribute"));
            item.setAttributeRandomGroupId((String) meta.get("AttributeRandomGroupID"));
            item.setItemSetId((Integer) meta.get("ItemSetID"));
            item.setGachaGroupId((Integer) meta.get("GachaGroupId"));

            // 구매 정보
            item.setBuyPriceType((String) meta.get("Buy_Price_Type"));
            item.setBuyId((Integer) meta.get("Buy_id"));
            item.setBuyPrice((Integer) meta.get("Buy_price"));
            item.setBuffId((Integer) meta.get("buff_id"));
            item.setProductLink((String) meta.get("ProductLink"));
            item.setIsCartNBuy((Boolean) meta.get("is_CartNBuy"));
            item.setBuyDiscountRate((Integer) meta.get("Buy_Discount_Rate"));

            // 기타
            item.setPropSmallType((String) meta.get("PropSmallType"));
            item.setUgqAction((String) meta.get("UGQAction"));
            item.setLinkedLand((Integer) meta.get("LinkedLand"));
            item.setIsUiOnly((Boolean) meta.get("IsUiOnly"));
            item.setBeaconShopGoldFee((Integer) meta.get("BeaconShopGoldFee"));
            item.setIsBeaconShop((Boolean) meta.get("is_BeaconShop"));

            items.put(item.getItemId(), item);
        });

        log.info("loadItems {} Load Complete", EMetaData.ITEM_DATA.getFileName());

    }

    // 의상 타입 데이터 로드
    public void loadClothType(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.CLOTH_TYPE_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("clothType data is empty or file not found: {}", EMetaData.TOOL_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaClothTypeData item = new MetaClothTypeData();
            item.setMetaId((Integer)meta.get("Meta_id"));
            item.setSmallType((String)meta.get("SmallType"));
            item.setEquipSlotType((String)meta.get("EquipSlotType"));
            clothTypes.put(item.getMetaId(), item);
        });

        log.info("loadClothType {} Load Complete", EMetaData.CLOTH_TYPE_DATA.getFileName());
    }

    // 도구 정보 데이터 로드
    public void loadToolItems(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.TOOL_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("tool data is empty or file not found: {}", EMetaData.TOOL_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaToolData item = new MetaToolData();
            item.setToolId((Integer)meta.get("tool_id"));
            item.setToolName((String)meta.get("tool_name"));
            toolItems.put(item.getToolId(), item);
        });

        log.info("loadToolItems {} Load Complete", EMetaData.TOOL_DATA.getFileName());
    }

    // 금지어 데이터 로드
    public void loadBanWord(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.BAN_WORD_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("ban data is empty or file not found: {}", EMetaData.BAN_WORD_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            banWords.put((Integer)meta.get("Id"), (String)meta.get("Ban_Word"));
        });

        log.info("loadBanWord {} Load Complete", EMetaData.BAN_WORD_DATA.getFileName());
    }

    // 퀘스트 데이터 로드
    public void loadQuests(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.QUEST_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("quest data is empty or file not found: {}", EMetaData.QUEST_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaQuestData item = new MetaQuestData();
            Integer questId = (Integer)meta.get("QuestID");
            Integer taskNum = (Integer)meta.get("TaskNum");
            item.setQuestId(questId);
            item.setTaskNum(taskNum);
            item.setTaskName((String)meta.get("TaskName"));
            item.setCounter((Integer) meta.get("SetCounter"));
            quests.put(new MetaQuestKey(questId, taskNum), item);
        });

        log.info("loadQuests {} Load Complete", EMetaData.QUEST_DATA.getFileName());
    }

    // 빌딩 데이터 로드
    public void loadBuilding(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.BUILDING_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("building data is empty or file not found: {}", EMetaData.BUILDING_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            String building_name = (String)meta.get("BuildingName");
            if(building_name.isEmpty()) return;
            MetaBuildingData item = new MetaBuildingData();
            item.setBuildingId((Integer)meta.get("BuildingId"));
            item.setBuildingOpen((Boolean)meta.get("BuildingOpen"));
            item.setOwner((String)meta.get("Owner"));
            item.setEditor((String)meta.get("Editor"));
            item.setBuildingName(building_name);
            item.setBuildingDesc((String)meta.get("BuildingDesc"));
            item.setBuildingSize((String)meta.get("BuildingSize"));
            item.setInstanceSocket((Integer)meta.get("InstanceSocket"));
            buildings.put((Integer)meta.get("BuildingId"), item);
        });

        log.info("loadBuilding {} Load Complete", EMetaData.BUILDING_DATA.getFileName());
    }

    // 랜드 데이터 로드
    public void loadLand(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.LAND_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("land data is empty or file not found: {}", EMetaData.LAND_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            String land_name = (String)meta.get("LandName");
            if(land_name.isEmpty()) return;
            MetaLandData item = new MetaLandData();
            item.setLandId((Integer)meta.get("LandId"));
            item.setOwner((String)meta.get("Owner"));
            item.setEditor((String)meta.get("Editor"));
            Boolean nonAuction = (Boolean)meta.get("NonAuction");
            if(nonAuction != null)
                item.setNonAuction(nonAuction);
            item.setRentalStateSwitch((Boolean)meta.get("RentalStateSwitch"));
            item.setRentalAvailable((Boolean)meta.get("RentalAvailable"));
            item.setLandName(land_name);
            item.setLandDesc((String)meta.get("LandDesc"));
            item.setLandSize((String)meta.get("LandSize"));
            item.setLandType((String)meta.get("LandType"));
            item.setLinkedItem((Integer)meta.get("LinkedItem"));
            item.setCityType((String)meta.get("CityType"));
            item.setBuildingArea((String)meta.get("BuildingArea"));
            item.setBuildingId((Integer)meta.get("BuildingId"));
            item.setBuildingSocket((Integer)meta.get("BuildingSocket"));
            lands.put((Integer)meta.get("LandId"), item);
        });

        log.info("loadLand {} Load Complete", EMetaData.LAND_DATA.getFileName());
    }

    // 게임 모드 데이터 로드
    public void loadGameMode(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.GAME_MODE_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Game Mode data is empty or file not found: {}", EMetaData.GAME_MODE_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaGameModeData item = new MetaGameModeData();
            item.setId((Integer)meta.get("GameModeID"));
            item.setDesc((String)meta.get("GameModeDescription"));
            item.setGenreType((String)meta.get("GameGenreType"));
            item.setModeType((String)meta.get("GameModeType"));
            item.setModeConfigId((Integer)meta.get("GameModeConfigID"));
            item.setModeCommonId((Integer)meta.get("GameModeCommonID"));
            item.setInstanceId((Integer)meta.get("InstanceID"));
            item.setModeMatchId((Integer)meta.get("GameModeMatchID"));
            item.setModeRewardGroupId((Integer)meta.get("GameModeRewardGroupID"));
            item.setModeOptionId((Integer)meta.get("GameModeOptionID"));
            item.setModeStartId((Integer)meta.get("GameModeStartID"));
            item.setModeTeamId((Integer)meta.get("GameModeTeamID"));
            gameModes.put((Integer)meta.get("GameModeID"), item);
        });

        log.info("loadGameMode {} Load Complete", EMetaData.GAME_MODE_DATA.getFileName());
    }

    // 게임 모드 매칭 데이터 로드
    public void loadGameModeMatch(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.GAME_MODE_MATCH_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Game Mode Match data is empty or file not found: {}", EMetaData.GAME_MODE_MATCH_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaGameModeMatchData item = new MetaGameModeMatchData();
            item.setId((Integer)meta.get("GameModeMatchID"));
            item.setDesc((String)meta.get("GameModeMatchDescription"));
            item.setMmrCheck((Boolean)meta.get("MmrCheck"));
            item.setPartyMatchPlayerCountAbleArray((List<Integer>) meta.get("PartyMatchPlayerCountAbleArray"));
            item.setMatchWaitTimeSec((Integer)meta.get("MatchWaitTimeSec"));
            item.setGameModeMmrID((Integer)meta.get("GameModeMmrID"));
            item.setMatchRetryCount((Integer)meta.get("MatchRetryCount"));
            item.setMmrExpansionPhase((Integer)meta.get("MmrExpansionPhase"));
            item.setTeamAssignment(ETeamAssignmentType.valueOf((String)meta.get("TeamAssignment")));
            item.setJoinInProgress(EJoinInProgressType.valueOf((String)meta.get("JoinInProgress")));
            item.setJoinInMaxTimeSec((Integer)meta.get("JoinInMaxTimeSec"));
            item.setEntranceClosingTime((Integer)meta.get("EntranceClosingTime"));
            gameModeMatches.put((Integer)meta.get("GameModeMatchID"), item);
        });

        log.info("loadGameModeMatch {} Load Complete", EMetaData.GAME_MODE_DATA.getFileName());
    }

    // 게임 TPS_FFA 설정 데이터 로드
    public void loadGameModeFFAConfig(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.GAME_MODE_FFA_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("gameMode TPS FFA data is empty or file not found: {}", EMetaData.GAME_MODE_FFA_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaGameFFAConfigData item = new MetaGameFFAConfigData();
            item.setId((Integer)meta.get("GameModeTpsFfaID"));
            item.setDesc((String)meta.get("GameModeTpsFfaDescription"));
            item.setPlayerRespawnTime((Integer)meta.get("PlayerRespawnTime"));
            item.setDefaultRoundCount((Integer)meta.get("DefaultRoundCount"));
            item.setRoundTime((Integer)meta.get("RoundTime"));
            item.setNextRoundWaitTime((Integer)meta.get("NextRoundWaitTime"));
            item.setResultUIWaitTime((Integer)meta.get("ResultUIWaitTime"));
            item.setGetRewardTime((Integer)meta.get("GetRewardTime"));
            gameFFAConfigs.put((Integer)meta.get("GameModeTpsFfaID"), item);
        });

        log.info("loadGameModeFFAConfig {} Load Complete", EMetaData.GAME_MODE_FFA_DATA.getFileName());
    }

    // 게임 TPS_TDM 설정 데이터 로드
    public void loadGameModeTDMConfig(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.GAME_MODE_TDM_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Battle config data is empty or file not found: {}", EMetaData.GAME_MODE_TDM_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaBattleConfigData item = new MetaBattleConfigData();
            item.setId((Integer)meta.get("Id"));
            item.setDesc((String)meta.get("Description"));
            item.setPlayerRespawnTime((Integer)meta.get("PlayerRespawnTime"));
            item.setDefaultRoundCount((Integer)meta.get("DefaultRoundCount"));
            item.setRoundTime((Integer)meta.get("RoundTime"));
            item.setNextRoundWaitTime((Integer)meta.get("NextRoundWaitTime"));
            item.setResultUIWaitTime((Integer)meta.get("ResultUIWaitTime"));
            item.setGetRewardTime((Integer)meta.get("GetRewardTime"));
            battleConfigs.put((Integer)meta.get("Id"), item);
        });

        log.info("loadBattleConfig {} Load Complete", EMetaData.GAME_MODE_TDM_DATA.getFileName());
    }

    // 전투 설정 데이터 로드
    public void loadBattleConfig(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.BATTLE_CONFIG_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Battle config data is empty or file not found: {}", EMetaData.BATTLE_CONFIG_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaBattleConfigData item = new MetaBattleConfigData();
            item.setId((Integer)meta.get("Id"));
            item.setDesc((String)meta.get("Description"));
            item.setPlayerRespawnTime((Integer)meta.get("PlayerRespawnTime"));
            item.setDefaultRoundCount((Integer)meta.get("DefaultRoundCount"));
            item.setRoundTime((Integer)meta.get("RoundTime"));
            item.setNextRoundWaitTime((Integer)meta.get("NextRoundWaitTime"));
            item.setResultUIWaitTime((Integer)meta.get("ResultUIWaitTime"));
            item.setGetRewardTime((Integer)meta.get("GetRewardTime"));
            battleConfigs.put((Integer)meta.get("Id"), item);
        });

        log.info("loadBattleConfig {} Load Complete", EMetaData.BATTLE_CONFIG_DATA.getFileName());
    }

    // 전투 보상 데이터 로드
    public void loadBattleReward(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.BATTLE_REWARD_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Battle reward data is empty or file not found: {}", EMetaData.BATTLE_REWARD_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaBattleRewardData item = new MetaBattleRewardData();
            item.setId((Integer)meta.get("Id"));
            item.setDesc((String)meta.get("Description"));
            item.setGroupID((Integer)meta.get("GroupID"));
            item.setChargeLevel((Integer)meta.get("ChargeLevel"));
            item.setChargeTime((Integer)meta.get("ChargeTime"));
            item.setRewardItemID((Integer)meta.get("RewardItemID"));
            item.setRewardCount((Integer)meta.get("RewardCount"));
            battleRewards.put((Integer)meta.get("Id"), item);
        });

        log.info("loadBattleReward {} Load Complete", EMetaData.BATTLE_REWARD_DATA.getFileName());
    }

    // 시스템메일 데이터 로드
    public void loadSystemMail(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.SYSTEM_MAIL_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("System Mail data is empty or file not found: {}", EMetaData.SYSTEM_MAIL_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaSystemMailData item = new MetaSystemMailData();
            item.setKey((String)meta.get("Key"));
            item.setMailTitle((String)meta.get("Mail_Title"));
            item.setMailDesc((String)meta.get("Mail_Desc"));
            item.setSender((String)meta.get("Sender"));
            systemMails.put((String)meta.get("Key"), item);
        });

        log.info("loadSystemMail {} Load Complete", EMetaData.SYSTEM_MAIL_DATA.getFileName());
    }

    // 웹링크 데이터 로드
    public void loadWebLinkLocalize(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.WEB_LINK_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Web Link Localize data is empty or file not found: {}", EMetaData.WEB_LINK_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaWebLinkData item = new MetaWebLinkData();

            item.setKey((String) meta.get("Key"));
            item.setKo((String) meta.get("Ko"));
            item.setEn((String) meta.get("En"));
            item.setJa((String) meta.get("Ja"));

            webLinks.add(item);
        });

        log.info("loadWebLinkLocalize {} Load Complete", EMetaData.WEB_LINK_DATA.getFileName());
    }

    // 브랜드 데이터 로드
    public void loadBrand(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.BRAND_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Brand data is empty or file not found: {}", EMetaData.BRAND_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaBrandData item = new MetaBrandData();

            item.setId((Integer) meta.get("ID"));
            item.setBrandName((String) meta.get("BrandName"));
            item.setLogoLeft((String) meta.get("LogoLeft"));
            item.setLogoCenter((String) meta.get("LogoCenter"));
            item.setLogoRight((String) meta.get("LogoRight"));
            item.setLogoText((String) meta.get("LogoText"));

            brands.add(item);
        });

        log.info("loadBrand {} Load Complete", EMetaData.BRAND_DATA.getFileName());
    }

    // 버프 데이터 로드
    public void loadBuff(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.BUFF_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Buff data is empty or file not found: {}", EMetaData.BUFF_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaBuffData item = new MetaBuffData();

            item.setBuffId((Integer) meta.get("buff_id"));
            item.setBuffName((String) meta.get("buff_name"));
            item.setBuffDescription((String) meta.get("buff_description"));
            item.setBuffCategory((String) meta.get("buff_category"));
            item.setBuffChannel((Integer) meta.get("buff_channel"));
            item.setBuffPriority((Integer) meta.get("buff_priority"));
            item.setActionBuffId((Integer) meta.get("action_buff_id"));

            @SuppressWarnings("unchecked")
            List<Map<String, Object>> traitsData = (List<Map<String, Object>>) meta.get("Traits");
            if (traitsData != null) {
                List<MetaBuffData.Trait> traits = new ArrayList<>();
                traitsData.forEach(traitMap -> {
                    MetaBuffData.Trait trait = new MetaBuffData.Trait();
                    trait.setAttribute((String) traitMap.get("Attribute"));
                    trait.setValue((Integer) traitMap.get("Value"));
                    trait.setOperation((String) traitMap.get("Operation"));
                    traits.add(trait);
                });
                item.setTraits(traits);
            }

            // 프롭 관련
            item.setPropmeshName((String) meta.get("propmesh_name"));
            item.setPropmeshNameOpacity((String) meta.get("propmesh_name_opacity"));
            item.setUseRequired((Integer) meta.get("use_required"));

            // 가이드 관련
            item.setInactiveRange((Integer) meta.get("InactiveRange"));
            item.setGuideHeight((Integer) meta.get("GuideHeight"));
            item.setGuideOffset((Integer) meta.get("GuideOffset"));
            Number guideScaleValue = (Number) meta.get("GuideScale");
            item.setGuideScale(guideScaleValue.doubleValue());
            item.setPropEffect((String) meta.get("prop_effect"));

            // 시작/종료 조건
            item.setBuffStartCondition((String) meta.get("buff_start_condition"));
            item.setBuffStartConditionValue((Integer) meta.get("buff_start_condition_value"));
            item.setBuffEndCondition((String) meta.get("buff_end_condition"));
            item.setBuffEndConditionValue((Integer) meta.get("buff_end_condition_value"));
            item.setDurationTime((Integer) meta.get("duration_time"));

            // 실행 관련
            item.setBuffEndExecutionType((String) meta.get("buff_end_execution_type"));
            item.setBuffEndExecutionValue((Integer) meta.get("buff_end_execution_value"));

            // 어태치 관련
            item.setAttachEffectBp((String) meta.get("attach_effect_bp"));
            item.setAttachAvatarSocket((String) meta.get("attach_avatar_socket"));
            item.setToolId((Integer) meta.get("tool_id"));

            // 액션/모션 관련
            item.setBuffActionName((String) meta.get("buff_action_name"));
            item.setBuffMotionSet((String) meta.get("buff_motion_set"));
            item.setBuffHandType((String) meta.get("buff_hand_type"));
            item.setBuffActivateName((String) meta.get("buff_activate_name"));
            item.setBuffDeactivateName((String) meta.get("buff_deactivate_name"));
            item.setBuffSwapName((String) meta.get("buff_swap_name"));

            // UI 관련
            item.setBuffIcon2D((String) meta.get("buff_icon_2D"));
            item.setBuffActionCooltime((Integer) meta.get("buff_action_cooltime"));
            item.setUsingAimOffset((String) meta.get("using_aim_offset"));

            // 플래그들
            item.setUserDetachable((Boolean) meta.get("user_detachable"));
            item.setNormalRemain((Boolean) meta.get("is_normal_remain"));
            item.setConcertRemain((Boolean) meta.get("is_concert_remain"));
            item.setMovieRemain((Boolean) meta.get("is_movie_remain"));
            item.setMeetingRemain((Boolean) meta.get("is_meeting_remain"));
            item.setMyhomeRemain((Boolean) meta.get("is_myhome_remain"));
            item.setBeaconRemain((Boolean) meta.get("is_beacon_remain"));
            item.setDressroomRemain((Boolean) meta.get("is_dressroom_remain"));

            buffs.add(item);
        });

        log.info("loadBuff {} Load Complete", EMetaData.BUFF_DATA.getFileName());
    }

    // 속성랜덤그룹 데이터 로드
    public void loadAttributeRandomGroup(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.ATTRIBUTE_RANDOM_GROUP_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Attribute Random Group data is empty or file not found: {}", EMetaData.ATTRIBUTE_RANDOM_GROUP_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaAttributeRandomGroupData item = new MetaAttributeRandomGroupData();

            item.setKey((Integer) meta.get("Key"));
            item.setGroupId((String) meta.get("GroupID"));
            item.setAttribute((String) meta.get("Attribute"));
            item.setWeight((Integer) meta.get("Weight"));

            attributeRandomGroups.add(item);
        });

        log.info("loadAttributeRandomGroup {} Load Complete", EMetaData.ATTRIBUTE_RANDOM_GROUP_DATA.getFileName());
    }

    // 아이템세트 데이터 로드
    public void loadItemSet(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.ITEM_SET_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Item Set data is empty or file not found: {}", EMetaData.ITEM_SET_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaItemSetData item = new MetaItemSetData();

            item.setId((Integer) meta.get("ID"));
            item.setName((String) meta.get("Name"));

            @SuppressWarnings("unchecked")
            List<String> itemsData = (List<String>) meta.get("Items");
            item.setItems(itemsData);

            @SuppressWarnings("unchecked")
            List<Map<String, Object>> setEffectsData = (List<Map<String, Object>>) meta.get("SetEfffects");
            if (setEffectsData != null) {
                List<MetaItemSetData.SetEffect> setEffects = new ArrayList<>();
                setEffectsData.forEach(effectMap -> {
                    MetaItemSetData.SetEffect setEffect = new MetaItemSetData.SetEffect();
                    setEffect.setRequirementCount((Integer) effectMap.get("RequirementCount"));
                    setEffect.setAttributeName((String) effectMap.get("AttributeName"));
                    setEffect.setAttributeValue((Integer) effectMap.get("AttributeValue"));
                    setEffects.add(setEffect);
                });
                item.setSetEffects(setEffects);
            }

            itemSets.add(item);
        });

        log.info("loadItemSet {} Load Complete", EMetaData.ITEM_SET_DATA.getFileName());
    }

    // 랜덤박스 데이터 로드
    public void loadGacha(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.GACHA_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Gacha data is empty or file not found: {}", EMetaData.GACHA_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaGachaData item = new MetaGachaData();

            item.setId((Integer) meta.get("Id"));
            item.setGroupId((Integer) meta.get("GroupId"));
            item.setWeight((Integer) meta.get("Weight"));

            @SuppressWarnings("unchecked")
            Map<String, Object> rewardData = (Map<String, Object>) meta.get("Reward");
            if (rewardData != null) {
                MetaGachaData.Reward reward = new MetaGachaData.Reward();

                @SuppressWarnings("unchecked")
                Map<String, Object> currencyData = (Map<String, Object>) rewardData.get("Currency");
                if (currencyData != null) {
                    MetaGachaData.Currency currency = new MetaGachaData.Currency();
                    currency.setId((Integer) currencyData.get("Id"));
                    currency.setValue(((Number) currencyData.get("Value")).doubleValue());
                    reward.setCurrency(currency);
                }

                item.setReward(reward);
            }

            gachas.add(item);
        });

        log.info("loadGacha {} Load Complete", EMetaData.GACHA_DATA.getFileName());
    }

    // 제작 데이터 로드
    public void loadCrafting(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.CRAFTING_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Crafting data is empty or file not found: {}", EMetaData.CRAFTING_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaCraftingData item = new MetaCraftingData();

            // 기본 정보
            item.setId((Integer) meta.get("Id"));
            item.setPropSmallType((String) meta.get("PropSmallType"));
            item.setCraftingItemId((Integer) meta.get("Crafting_ItemId"));
            item.setCraftingItemValue((Integer) meta.get("Crafting_ItemValue"));
            item.setRecipeType((String) meta.get("RecipeType"));
            item.setRecipeItemId((Integer) meta.get("Recipe_ItemId"));

            // Material 배열 처리
            @SuppressWarnings("unchecked")
            List<Map<String, Object>> materialData = (List<Map<String, Object>>) meta.get("Material");
            if (materialData != null) {
                List<MetaCraftingData.Material> materials = new ArrayList<>();
                materialData.forEach(materialMap -> {
                    MetaCraftingData.Material material = new MetaCraftingData.Material();
                    material.setItemId((Integer) materialMap.get("ItemId"));
                    material.setItemValue((Integer) materialMap.get("ItemValue"));
                    materials.add(material);
                });
                item.setMaterials(materials);
            }

            @SuppressWarnings("unchecked")
            List<Map<String, Object>> attributeData = (List<Map<String, Object>>) meta.get("Attribute");
            if (attributeData != null) {
                List<MetaCraftingData.Attribute> attributes = new ArrayList<>();
                attributeData.forEach(attributeMap -> {
                    MetaCraftingData.Attribute attribute = new MetaCraftingData.Attribute();
                    attribute.setAttributeName((String) attributeMap.get("AttributeName"));
                    attribute.setAttributeValue((Integer) attributeMap.get("AttributeValue"));
                    attributes.add(attribute);
                });
                item.setAttributes(attributes);
            }

            @SuppressWarnings("unchecked")
            List<Integer> propData = (List<Integer>) meta.get("Prop");
            item.setProps(propData);

            // 시간 및 제한 정보
            item.setCraftingTime((Integer) meta.get("CraftingTime"));
            item.setBeaconReduceTime((Integer) meta.get("Beacon_ReduceTime"));
            item.setBeaconBonusItemId((Integer) meta.get("Beacon_BonusItemId"));
            item.setMaxCraftLimit((Integer) meta.get("max_craft_limit"));

            craftings.add(item);
        });

        log.info("loadCrafting {} Load Complete", EMetaData.CRAFTING_DATA.getFileName());
    }

    // 랜덤박스 데이터 로드
    public void loadCurrency(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.CURRENCY_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Currency data is empty or file not found: {}", EMetaData.CURRENCY_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaCurrencyData item = new MetaCurrencyData();

            item.setId((Integer) meta.get("Id"));
            item.setCurrencyType((String) meta.get("CurrencyType"));
            item.setName((String) meta.get("Name"));
            item.setDescription((String) meta.get("Description"));
            item.setMaxCount((Integer) meta.get("MaxCount"));
            item.setIconPath((String) meta.get("IconPath"));
            item.setItemId((Integer) meta.get("ItemID"));

            currencies.add(item);
        });

        log.info("loadCurrency {} Load Complete", EMetaData.CURRENCY_DATA.getFileName());
    }

    // 랜덤박스 데이터 로드
    public void loadRanking(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.RANKING_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Ranking data is empty or file not found: {}", EMetaData.RANKING_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaRankingData item = new MetaRankingData();

            item.setId((Integer) meta.get("RankingId"));
            item.setDesc((String) meta.get("desc_"));
            item.setRankingType((String) meta.get("RankingType"));
            item.setTypeId((Integer) meta.get("TypeId"));
            item.setTypeValue((Integer) meta.get("TypeValue"));
            item.setEventType((String) meta.get("EventType"));
            item.setSortType((String) meta.get("SortType"));
            item.setScoreType((String) meta.get("ScoreType"));
            item.setScoreModifyType((String) meta.get("ScoreModifyType"));

            rankings.add(item);
        });

        log.info("loadRanking {} Load Complete", EMetaData.RANKING_DATA.getFileName());
    }

    //이벤트 스코어
    public void loadEventActionScore(){
        List<Map<String, Object>> metaList = jsonFileReader.readJsonFile(EMetaData.EVENT_ACTION_SCORE_DATA.getFileName());
        if(metaList == null || metaList.isEmpty()) {
            log.warn("Event Action Score data is empty or file not found: {}", EMetaData.EVENT_ACTION_SCORE_DATA.getFileName());
            return;
        }

        metaList.forEach(meta -> {
            MetaEventActionScoreData item = new MetaEventActionScoreData();

            item.setId((Integer) meta.get("Index"));
            item.setDescription((String) meta.get("desc_"));
            item.setGroupId((Integer) meta.get("GroupId"));
            item.setEventTarget((String) meta.get("EventTarget"));
            item.setEvent((String) meta.get("Event"));
            item.setEventCondition1((String) meta.get("EventCondition1"));
            item.setEventCondition2((String) meta.get("EventCondition2"));
            item.setEventCondition3((String) meta.get("EventCondition3"));
            item.setScore((Integer) meta.get("Score"));
            item.setScoreModifyType((String) meta.get("ScoreModifyType"));
            item.setActive((Boolean) meta.get("Active"));

            eventActionScoreDatas.add(item);
        });

        log.info("loadEventActionScore {} Load Complete", EMetaData.EVENT_ACTION_SCORE_DATA.getFileName());
    }
}
