using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Tornado3_2026Election.Common;
using Tornado3_2026Election.Domain;

namespace Tornado3_2026Election.ViewModels;

public sealed class StationFilterItemViewModel : ObservableObject
{
    private static readonly string[] SupportedRegions =
    [
        "서울",
        "부산",
        "대구",
        "인천",
        "광주",
        "대전",
        "울산",
        "세종",
        "경기",
        "강원",
        "충북",
        "충남",
        "전북",
        "전남",
        "경북",
        "경남",
        "제주"
    ];

    private static readonly IReadOnlyDictionary<string, string> RegionAliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
    {
        ["서울"] = "서울",
        ["서울특별시"] = "서울",
        ["부산"] = "부산",
        ["부산광역시"] = "부산",
        ["대구"] = "대구",
        ["대구광역시"] = "대구",
        ["인천"] = "인천",
        ["인천광역시"] = "인천",
        ["광주"] = "광주",
        ["광주광역시"] = "광주",
        ["대전"] = "대전",
        ["대전광역시"] = "대전",
        ["울산"] = "울산",
        ["울산광역시"] = "울산",
        ["세종"] = "세종",
        ["세종특별자치시"] = "세종",
        ["경기"] = "경기",
        ["경기도"] = "경기",
        ["강원"] = "강원",
        ["강원도"] = "강원",
        ["강원특별자치도"] = "강원",
        ["충북"] = "충북",
        ["충청북도"] = "충북",
        ["충남"] = "충남",
        ["충청남도"] = "충남",
        ["전북"] = "전북",
        ["전라북도"] = "전북",
        ["전북특별자치도"] = "전북",
        ["전남"] = "전남",
        ["전라남도"] = "전남",
        ["경북"] = "경북",
        ["경상북도"] = "경북",
        ["경남"] = "경남",
        ["경상남도"] = "경남",
        ["제주"] = "제주",
        ["제주도"] = "제주",
        ["제주특별자치도"] = "제주"
    };

    private VideoWallLayoutPreset _videoWallLayoutPreset;

    public StationFilterItemViewModel(BroadcastStationProfile station)
    {
        Id = station.Id;
        Name = station.Name;
        LogoAssetPath = station.LogoAssetPath;
        _videoWallLayoutPreset = station.VideoWallLayoutPreset;

        var selectedRegions = ParseRegions(station.RegionFilters);
        Regions = new ObservableCollection<RegionOptionViewModel>(
            SupportedRegions.Select(region => new RegionOptionViewModel(region, selectedRegions.Contains(region), NotifyRegionSelectionChanged)));
    }

    public string Id { get; }

    public string Name { get; }

    public string LogoAssetPath { get; }

    public ObservableCollection<RegionOptionViewModel> Regions { get; }

    public VideoWallLayoutPreset VideoWallLayoutPreset
    {
        get => _videoWallLayoutPreset;
        set
        {
            if (SetProperty(ref _videoWallLayoutPreset, value))
            {
                OnPropertyChanged(nameof(VideoWallLayoutSummary));
            }
        }
    }

    public string RegionFiltersText
    {
        get => string.Join(", ", Regions.Where(region => region.IsSelected).Select(region => region.Name));
        set => ApplyRegionSelection(value.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries));
    }

    public int SelectedRegionCount => Regions.Count(region => region.IsSelected);

    public string RegionSelectionSummary
        => SelectedRegionCount == 0 ? "선택된 시도가 없습니다." : $"선택된 시도 {SelectedRegionCount}개";

    public string VideoWallLayoutSummary => VideoWallLayoutPreset switch
    {
        VideoWallLayoutPreset.Wall3840x810 => "3840 x 810 VideoWall",
        VideoWallLayoutPreset.Wall2880x1080 => "2880 x 1080 VideoWall",
        VideoWallLayoutPreset.UltraWide8316x1080 => "8316 x 1080 VideoWall",
        _ => "씬 기준 자동 감지"
    };

    public BroadcastStationProfile ToProfile()
    {
        return new BroadcastStationProfile
        {
            Id = Id,
            Name = Name,
            LogoAssetPath = LogoAssetPath,
            VideoWallLayoutPreset = VideoWallLayoutPreset,
            RegionFilters = Regions
                .Where(region => region.IsSelected)
                .Select(region => region.Name)
                .ToArray()
        };
    }

    private void ApplyRegionSelection(IEnumerable<string> regionNames)
    {
        var selectedRegions = ParseRegions(regionNames);
        foreach (var region in Regions)
        {
            region.IsSelected = selectedRegions.Contains(region.Name);
        }

        NotifyRegionSelectionChanged();
    }

    private void NotifyRegionSelectionChanged()
    {
        OnPropertyChanged(nameof(RegionFiltersText), nameof(SelectedRegionCount), nameof(RegionSelectionSummary));
    }

    private static HashSet<string> ParseRegions(IEnumerable<string> regionNames)
    {
        var parsedRegions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

        foreach (var regionName in regionNames)
        {
            var normalizedRegion = NormalizeRegion(regionName);
            if (SupportedRegions.Contains(normalizedRegion, StringComparer.Ordinal))
            {
                parsedRegions.Add(normalizedRegion);
            }
        }

        return parsedRegions;
    }

    private static string NormalizeRegion(string? regionName)
    {
        if (string.IsNullOrWhiteSpace(regionName))
        {
            return string.Empty;
        }

        var trimmedRegion = regionName.Trim();
        return RegionAliases.TryGetValue(trimmedRegion, out var normalizedRegion)
            ? normalizedRegion
            : trimmedRegion;
    }
}
