Загрузка данных


using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Windows.Forms;

namespace QualityTest_Inventory
{
    public partial class Form1 : Form
    {
        // Словари для хранения строк текущего языка и эталонных ключей
        private Dictionary<string, string> currentTranslations = new Dictionary<string, string>();
        private HashSet<string> referenceKeys = new HashSet<string>();
        
        // Переменные логики инвентаря
        private double totalWeight = 0.0;
        private const double WeightLimit = 50.0; // Предел веса
        private string currentLang = "ru"; // Язык по умолчанию

        public Form1()
        {
            InitializeComponent();
            SetupDataGridView();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 1. Инициализация и проверка целостности файлов локализации
            InitializeLocalizationSystem();

            // 2. Загрузка конфигурации (сохранение между сеансами)
            LoadConfiguration();

            // 3. Применение выбранного языка и заполнение списков
            SwitchLanguage(currentLang);
        }

        // Настройка таблицы инвентаря
        private void SetupDataGridView()
        {
            dgvInventory.ColumnCount = 4;
            dgvInventory.Columns[0].Name = "Name";
            dgvInventory.Columns[1].Name = "CategoryKey"; // Скрытый ключ для локализации категории
            dgvInventory.Columns[2].Name = "Weight";
            dgvInventory.Columns[3].Name = "Quantity";
            
            // Сделаем красивое отображение названий столбцов на этапе применения языка
            dgvInventory.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dgvInventory.MultiSelect = false;
            dgvInventory.AllowUserToAddRows = false;
        }

        #region БЛОК ЛОКАЛИЗАЦИИ И ПРОВЕРКИ ЦЕЛОСТНОСТИ

        private void InitializeLocalizationSystem()
        {
            string ruPath = "ru.json";
            string enPath = "en.json";

            // Если файлов нет на диске, сообщаем об ошибке
            if (!File.Exists(ruPath) || !File.Exists(enPath))
            {
                lstLogs.Items.Add("[CRITICAL] Отсутствуют файлы ru.json или en.json!");
                return;
            }

            try
            {
                // Читаем все ключи из обоих файлов для формирования эталона (Объединение множеств)
                string ruJson = File.ReadAllText(ruPath);
                string enJson = File.ReadAllText(enPath);

                var ruDict = JsonSerializer.Deserialize<Dictionary<string, string>>(ruJson);
                var enDict = JsonSerializer.Deserialize<Dictionary<string, string>>(enJson);

                if (ruDict != null) foreach (var key in ruDict.Keys) referenceKeys.Add(key);
                if (enDict != null) foreach (var key in enDict.Keys) referenceKeys.Add(key);
            }
            catch (Exception ex)
            {
                lstLogs.Items.Add("[ERROR] Ошибка инициализации эталона: " + ex.Message);
            }
        }

        // Метод проверки полноты конкретного языкового файла
        private void ValidateLanguageFile(string langCode, Dictionary<string, string> targetDict)
        {
            foreach (string refKey in referenceKeys)
            {
                if (!targetDict.ContainsKey(refKey))
                {
                    // Вывод в лог GUI сообщения об отсутствии ключа
                    lstLogs.Items.Add($"[LOCALIZATION] Отсутствует строка: {refKey} в файле {langCode}.json");
                }
            }
        }

        // Централизованный метод получения строки по ключу с обработкой плейсхолдеров
        private string GetText(string key)
        {
            if (currentTranslations.ContainsKey(key))
            {
                return currentTranslations[key];
            }
            return $"[MISSING: {key}]"; // Placeholder при отсутствии ключа
        }

        private void SwitchLanguage(string langCode)
        {
            string filePath = $"{langCode}.json";
            if (!File.Exists(filePath)) return;

            try
            {
                string jsonContent = File.ReadAllText(filePath);
                var loaded = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent);
                
                if (loaded != null)
                {
                    currentTranslations = loaded;
                    // Проверка полноты перевода при каждой смене/загрузке языка
                    ValidateLanguageFile(langCode, currentTranslations);
                }
            }
            catch (Exception ex)
            {
                lstLogs.Items.Add($"[ERROR] Ошибка чтения {filePath}: " + ex.Message);
            }

            currentLang = langCode;
            SaveConfiguration(); // Сохраняем выбор в config.json
            ApplyLanguage();     // Немедленно обновляем весь GUI
        }

        // Централизованный метод обновления интерфейса
        private void ApplyLanguage()
        {
            // Меню
            menuInventory.Text = GetText("menu_inventory");
            menuCharacter.Text = GetText("menu_character");
            menuLanguage.Text = GetText("menu_language");

            // Метки формы
            lblItemName.Text = GetText("lbl_item_name");
            lblCategory.Text = GetText("lbl_category");
            lblWeight.Text = GetText("lbl_weight");
            lblQuantity.Text = GetText("lbl_quantity");

            // Кнопки
            btnAdd.Text = GetText("btn_add");
            btnUse.Text = GetText("btn_use");
            btnDelete.Text = GetText("btn_delete");

            // Статистика
            lblStatsTitle.Text = GetText("lbl_stats_title");
            lblTotalWeight.Text = string.Format(GetText("lbl_total_weight"), totalWeight);
            lblWeightLimit.Text = string.Format(GetText("lbl_weight_limit"), WeightLimit);

            // Перезаполнение ComboBox категорий с сохранением выбранного индекса
            int selectedCatIndex = cmbCategory.SelectedIndex;
            cmbCategory.Items.Clear();
            cmbCategory.Items.Add(GetText("cat_weapon"));
            cmbCategory.Items.Add(GetText("cat_armor"));
            cmbCategory.Items.Add(GetText("cat_potion"));
            cmbCategory.SelectedIndex = selectedCatIndex >= 0 ? selectedCatIndex : 0;

            // Динамическое обновление названий колонок DataGridView без перезапуска
            if (dgvInventory.Columns.Count >= 4)
            {
                dgvInventory.Columns[0].HeaderText = GetText("lbl_item_name").Replace(":", "");
                dgvInventory.Columns[1].HeaderText = GetText("lbl_category").Replace(":", "");
                dgvInventory.Columns[2].HeaderText = GetText("lbl_weight").Replace(":", "");
                dgvInventory.Columns[3].HeaderText = GetText("lbl_quantity").Replace(":", "");
            }

            // Локализация содержимого таблицы (динамический пересчет строк на лету)
            UpdateGridCategoriesText();
        }

        private void UpdateGridCategoriesText()
        {
            foreach (DataGridViewRow row in dgvInventory.Rows)
            {
                if (row.Cells[1].Value != null)
                {
                    string catKey = row.Cells[1].Value.ToString();
                    row.Cells[1].Value = catKey; // Оставляем ключ в значении, но визуально отобразим текст
                }
            }
        }

        #endregion

        #region КОНФИГУРАЦИЯ (CONFIG.JSON)

        private void LoadConfiguration()
        {
            string configPath = "config.json";
            if (!File.Exists(configPath))
            {
                // При первом запуске создаем файл с дефолтным русским языком
                currentLang = "ru";
                SaveConfiguration();
            }
            else
            {
                try
                {
                    string json = File.ReadAllText(configPath);
                    using (JsonDocument doc = JsonDocument.Parse(json))
                    {
                        if (doc.RootElement.TryGetProperty("current_language", out JsonElement langElement))
                        {
                            currentLang = langElement.GetString();
                        }
                    }
                }
                catch
                {
                    currentLang = "ru"; // В случае сбоя сбрасываем на русский
                }
            }
        }

        private void SaveConfiguration()
        {
            try
            {
                var configData = new { current_language = currentLang };
                string json = JsonSerializer.Serialize(configData);
                File.ReadAllText(json); // Симуляция записи/Запись на диск:
                File.WriteAllText("config.json", json);
            }
            catch (Exception ex)
            {
                lstLogs.Items.Add("[ERROR] Не удалось сохранить конфигурацию: " + ex.Message);
            }
        }

        #endregion

        #region ЛОГИКА ИГРОВОГО ИНВЕНТАРЯ (КНОПКИ И ДЕЙСТВИЯ)

        // Переключение языка через меню
        private void menuLangRu_Click(object sender, EventArgs e) => SwitchLanguage("ru");
        private void menuLangEn_Click(object sender, EventArgs e) => SwitchLanguage("en");

        // Кнопка Добавить
        private void btnAdd_Click(object sender, EventArgs e)
        {
            string name = txtItemName.Text.Trim();
            if (string.IsNullOrEmpty(name)) return;

            int catIndex = cmbCategory.SelectedIndex;
            string catKey = catIndex == 0 ? "cat_weapon" : (catIndex == 1 ? "cat_armor" : "cat_potion");

            double weight = (double)numWeight.Value;
            int quantity = (int)numQuantity.Value;

            double itemTotalWeight = weight * quantity;

            // Проверка превышения лимита
            if (totalWeight + itemTotalWeight > WeightLimit)
            {
                MessageBox.Show(GetText("msg_overflow"), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                lstLogs.Items.Add($"[SYSTEM] {GetText("msg_overflow")}");
                return;
            }

            // Добавление в таблицу: имя, текстовое представление категории, вес, количество
            dgvInventory.Rows.Add(name, GetText(catKey), weight, quantity);
            
            totalWeight += itemTotalWeight;
            ApplyLanguage(); // Обновляем статистику веса
            
            txtItemName.Clear();
            numWeight.Value = 1;
            numQuantity.Value = 1;
        }

        // Кнопка Использовать
        private void btnUse_Click(object sender, EventArgs e)
        {
            if (dgvInventory.SelectedRows.Count > 0)
            {
                DataGridViewRow row = dgvInventory.SelectedRows[0];
                string itemName = row.Cells[0].Value.ToString();
                double itemWeight = Convert.ToDouble(row.Cells[2].Value);
                int qty = Convert.ToInt32(row.Cells[3].Value);

                MessageBox.Show(string.Format(GetText("msg_used"), itemName), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Information);
                lstLogs.Items.Add($"[GAME] {string.Format(GetText("msg_used"), itemName)}");

                if (qty > 1)
                {
                    row.Cells[3].Value = qty - 1;
                }
                else
                {
                    dgvInventory.Rows.Remove(row);
                }

                totalWeight -= itemWeight;
                ApplyLanguage();
            }
            else
            {
                MessageBox.Show(GetText("msg_select_item"), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        // Кнопка Удалить
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (dgvInventory.SelectedRows.Count > 0)
            {
                DataGridViewRow row = dgvInventory.SelectedRows[0];
                double itemWeight = Convert.ToDouble(row.Cells[2].Value);
                int qty = Convert.ToInt32(row.Cells[3].Value);

                totalWeight -= (itemWeight * qty);
                dgvInventory.Rows.Remove(row);

                ApplyLanguage();
            }
            else
            {
                MessageBox.Show(GetText("msg_select_item"), "RPG System", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        #endregion
    }
}