using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

//예전에 쓴 작성한 개소리 1% 포함 클래스를 여기서 그대로 쓸줄은 몰랐는데
//근데 이제 코드 단순화 1%도 추가 함유된
//그럼 101%임?

/// <summary>
/// ini를 통해 프로그램의 설정을 가져오거나 쓰게하는 클래스입니다.
/// </summary>
/// <remarks>
/// 
/// </remarks>
public class Jobini
{
    private Dictionary<string, string> iniData;
    private readonly string filePath;

    //어떻게 이름이 ini ini t
    public Jobini(string filePath)
    {
        this.iniData = ReadSetting(filePath);
        this.filePath = filePath;
    }
    /// <summary>
    /// inijob클래스를 생성합니다. 생성전에 데이터를 전부 삭제합니다.
    /// </summary>
    /// <param name="filePath">값을 저장시킬 파일의 경로입니다.</param>
    /// <param name="needRefrash">기존에 저장된 값을 모두 삭제후 다시 기록합니다. 기본값은 false입니다.</param>
    public Jobini(string filePath, bool needRefrash = false)
    {
        if (needRefrash || File.Exists(filePath))
        {
            File.Delete(filePath);
        }
        //File.Delete(filePath);
        this.iniData = ReadSetting(filePath);
        this.filePath = filePath;
        //file file = new();
    }


    private static Dictionary<string, string> ReadSetting(string filePath)
    {
        Dictionary<string, string> iniData = [];

        try
        {
            if (!File.Exists(filePath))
                File.Create(filePath);

            string[] lines = File.ReadAllLines(filePath);

            foreach (var line in lines)
            {
                if (string.IsNullOrWhiteSpace(line) || line.StartsWith(";"))
                    continue;

                string[] readingLine = line.Split('=');

                string key = readingLine[0].Trim();
                string value = readingLine.Length > 1 ? readingLine[1].Trim() : string.Empty;
                iniData[key] = value;
            }
        }
        catch (Exception e)
        {
            //   eeee
            //  e    e
            //  eeeee
            //  e
            //   eeeee
            Console.WriteLine(e);
        }
        return iniData;
    }

    public void IniWrite(string key, string value)
    {
        if (!iniData.TryAdd(key, value))
        {
            iniData[key] = value;
        }

        File.WriteAllLines(filePath, iniData.Select(kv => $"{kv.Key} = {kv.Value}"));
    }

    public string? IniRead(string key)
    {
        if (iniData.TryGetValue(key, out string? value))
        {
            return value;
        }
        return null;
    }

    /// <summary>
    /// null값이 반환되지않는 read입니다 검색하는 key가 없으면 제공되는 인수로
    /// key와 value를 작성후 반환합니다.
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    public string NotNullableiniRead(string key, string value = "0")
    {
        if (iniData.TryGetValue(key, out string? ivalue))
        {
            return ivalue;
        }
        this.IniWrite(key, value);
        return value;
    }

    public int IniCount()
    {
        return iniData.Count;
    }

    public bool IniDeleteKey(string key)
    {
        string trimKey = key.Trim();

        if (!iniData.ContainsKey(trimKey))
        {
            return false;
        }

        iniData.Remove(trimKey);

        File.WriteAllLines(filePath, iniData.Select(kv => $"{kv.Key} = {kv.Value}"));

        UpdateDictionary();

        return true;
    }

    private void UpdateDictionary()
    {
        this.iniData = ReadSetting(filePath);
    }

    public void Clear()
    {
        iniData.Clear();
    }

    public Dictionary<string,string> ReadDictionary()
    {
        return this.iniData;
    }
}