#nullable enable

using System;
using System.Collections.Generic;

namespace UVC.Data
{
    /// <summary>
    /// URL 주소를 키-값 쌍으로 저장하고 관리하는 클래스입니다.
    /// </summary>
    public static class URLList
    {
        /// <summary>
        /// URL을 저장하는 내부 Dictionary 컬렉션
        /// </summary>
        private static Dictionary<string, string> urls = new Dictionary<string, string>();

        /// <summary>
        /// 지정된 키와 URL을 컬렉션에 추가합니다. 키가 이미 존재하면 URL을 업데이트합니다.
        /// </summary>
        /// <param name="key">URL에 접근하기 위한 고유 키</param>
        /// <param name="url">저장할 URL 문자열</param>
        /// <example>
        /// <code>
        /// URLList.Add("google", "https://www.google.com");
        /// URLList.Add("naver", "https://www.naver.com");
        /// 
        /// // 기존 키의 URL 업데이트
        /// URLList.Add("google", "https://www.google.co.kr");
        /// </code>
        /// </example>
        public static void Add(string key, string url)
        {
            if (!urls.ContainsKey(key))
            {
                urls.Add(key, url);
            }
            else
            {
                urls[key] = url; // Update existing URL
            }
        }

        /// <summary>
        /// 지정된 키에 해당하는 URL을 컬렉션에서 제거합니다.
        /// </summary>
        /// <param name="key">제거할 URL의 키</param>
        /// <example>
        /// <code>
        /// URLList.Add("temp", "https://www.temp.com");
        /// 
        /// // URL 제거
        /// URLList.Remove("temp");
        /// 
        /// // 존재하지 않는 키 제거 시도(아무 일도 발생하지 않음)
        /// URLList.Remove("nonexistent");
        /// </code>
        /// </example>
        public static void Remove(string key)
        {
            if (urls.ContainsKey(key))
            {
                urls.Remove(key);
            }
        }

        /// <summary>
        /// 지정된 키가 컬렉션에 존재하는지 확인합니다.
        /// </summary>
        /// <param name="key">확인할 키</param>
        /// <returns>키가 존재하면 true, 그렇지 않으면 false</returns>
        /// <example>
        /// <code>
        /// URLList.Add("github", "https://github.com");
        /// 
        /// // 키 존재 여부 확인
        /// if(URLList.ContainsKey("github"))
        /// {
        ///     Console.WriteLine("GitHub URL이 존재합니다.");
        /// }
        /// 
        /// if(!URLList.ContainsKey("gitlab"))
        /// {
        ///     Console.WriteLine("GitLab URL이 존재하지 않습니다.");
        /// }
        /// </code>
        /// </example>
        public static bool ContainsKey(string key)
        {
            return urls.ContainsKey(key);
        }

        /// <summary>
        /// 지정된 키에 해당하는 URL을 반환합니다.
        /// </summary>
        /// <param name="key">가져올 URL의 키</param>
        /// <returns>키에 해당하는 URL 또는 키가 존재하지 않을 경우 null</returns>
        /// <example>
        /// <code>
        /// URLList.Add("youtube", "https://www.youtube.com");
        /// 
        /// // URL 가져오기
        /// string youtubeUrl = URLList.Get("youtube");
        /// if (youtubeUrl != null)
        /// {
        ///     Console.WriteLine($"YouTube URL: {youtubeUrl}");
        /// }
        /// 
        /// // 존재하지 않는 키로 URL 가져오기
        /// string nullUrl = URLList.Get("nonexistent");
        /// if (nullUrl == null)
        /// {
        ///     Console.WriteLine("URL이 존재하지 않습니다.");
        /// }
        /// </code>
        /// </example>
        public static string? Get(string key)
        {
            if (urls.TryGetValue(key, out string url))
            {
                return url;
            }
            return null; // or throw an exception if preferred
        }

        /// <summary>
        /// URL에서 도메인 부분을 추출합니다.
        /// </summary>
        /// <param name="url">도메인을 추출할 URL</param>
        /// <returns>추출된 도메인 또는 파싱 실패 시 null</returns>
        /// <example>
        /// <code>
        /// string domain = URLList.ExtractDomain("https://www.example.com/path/page.html");
        /// Console.WriteLine(domain); // 출력: www.example.com
        /// </code>
        /// </example>
        public static string? ExtractDomain(string url)
        {
            if (string.IsNullOrEmpty(url))
                return null;

            try
            {
                Uri uri = new Uri(url);
                return uri.Host;
            }
            catch (UriFormatException)
            {
                return null;
            }
        }
    }
}