using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class SongDetailPanel : MonoBehaviour
{
    [Header("곡 정보")]
    [SerializeField] private TMP_Text titleText;
    [SerializeField] private TMP_Text artistText;
    [SerializeField] private TMP_Text infoText;

    [Header("난이도 버튼")]
    [SerializeField] private Button btnNormal;
    [SerializeField] private Button btnHard;
    [SerializeField] private Button btnExpert;
    [SerializeField] private Button btnExpertPlus;

    [Header("액션 버튼")]
    [SerializeField] private Button downloadButton;
    [SerializeField] private Button deleteButton;
    [SerializeField] private Button playButton;
    [SerializeField] private Button closeButton;

    [Header("진행률")]
    [SerializeField] private GameObject progressGroup;
    [SerializeField] private Slider     progressSlider;
    [SerializeField] private TMP_Text   progressText;

    [Header("씬 이름")]
    [SerializeField] private string gameSceneName = "Game";

    private static readonly Color SelectedColor   = new Color(0.4f, 0.8f, 1f);
    private static readonly Color DeselectedColor = Color.white;

    private SongInfo          currentSong;
    private string            selectedDifficulty;
    private DownloadManager   downloadManager;
    private SongSelectManager selectManager;

    private readonly (string key, System.Func<SongDetailPanel, Button> btn)[] diffSlots =
    {
        ("normal",     p => p.btnNormal),
        ("hard",       p => p.btnHard),
        ("expert",     p => p.btnExpert),
        ("expertplus", p => p.btnExpertPlus),
    };

    // ── Public API ───────────────────────────────────────────

    public void Show(SongInfo song, DownloadManager dm, SongSelectManager sm)
    {
        currentSong        = song;
        downloadManager    = dm;
        selectManager      = sm;
        selectedDifficulty = null;

        titleText.text  = song.title;
        artistText.text = song.artist;
        infoText.text   = $"BPM {song.bpm}  |  {FormatDuration(song.duration)}";

        RefreshUI();
    }

    // ── UI 갱신 ──────────────────────────────────────────────

    private void RefreshUI()
    {
        bool downloaded = SongLibrary.Instance.IsSongDownloaded(currentSong.id);

        // 난이도 버튼 세팅
        foreach (var (key, getBtn) in diffSlots)
        {
            Button btn    = getBtn(this);
            bool   exists = currentSong.difficulties.Get(key) != null;

            btn.interactable = downloaded && exists;
            btn.onClick.RemoveAllListeners();

            if (downloaded && exists)
            {
                string captured = key;
                btn.onClick.AddListener(() => SelectDifficulty(captured));
            }
        }

        UpdateDiffColors();

        // 액션 버튼
        downloadButton.gameObject.SetActive(!downloaded);
        deleteButton.gameObject.SetActive(downloaded);
        playButton.interactable = downloaded && selectedDifficulty != null;
        progressGroup.SetActive(false);

        downloadButton.onClick.RemoveAllListeners();
        downloadButton.onClick.AddListener(OnDownloadClicked);

        deleteButton.onClick.RemoveAllListeners();
        deleteButton.onClick.AddListener(OnDeleteClicked);

        playButton.onClick.RemoveAllListeners();
        playButton.onClick.AddListener(OnPlayClicked);

        closeButton?.onClick.RemoveAllListeners();
        closeButton?.onClick.AddListener(() => gameObject.SetActive(false));
    }

    private void SelectDifficulty(string difficulty)
    {
        selectedDifficulty      = difficulty;
        playButton.interactable = true;
        UpdateDiffColors();
    }

    private void UpdateDiffColors()
    {
        foreach (var (key, getBtn) in diffSlots)
        {
            Button btn    = getBtn(this);
            var    colors = btn.colors;
            colors.normalColor = (key == selectedDifficulty) ? SelectedColor : DeselectedColor;
            btn.colors = colors;
        }
    }

    // ── 다운로드 (곡 단위 전체) ───────────────────────────────

    private void OnDownloadClicked()
    {
        StartCoroutine(DownloadAllCoroutine());
    }

    private IEnumerator DownloadAllCoroutine()
    {
        // 존재하는 난이도 수집
        var diffs = new List<string>();
        foreach (var (key, _) in diffSlots)
            if (currentSong.difficulties.Get(key) != null)
                diffs.Add(key);

        if (diffs.Count == 0) yield break;

        SetInteractable(false);
        progressGroup.SetActive(true);

        int  totalSteps = diffs.Count;
        int  doneSteps  = 0;
        bool failed     = false;

        foreach (string diff in diffs)
        {
            bool stepDone = false;

            downloadManager.DownloadSong(
                currentSong, diff,
                onProgress: p =>
                {
                    float overall        = (doneSteps + p) / totalSteps;
                    progressSlider.value = overall;
                    progressText.text    = $"{diffs[doneSteps < diffs.Count ? doneSteps : diffs.Count - 1].ToUpper()}  {(int)(overall * 100)}%";
                },
                onComplete: () =>
                {
                    SongLibrary.Instance.MarkDownloaded(currentSong.id, diff);
                    doneSteps++;
                    stepDone = true;
                },
                onError: err =>
                {
                    Debug.LogError($"[SongDetailPanel] {err}");
                    failed   = true;
                    stepDone = true;
                });

            yield return new WaitUntil(() => stepDone);
            if (failed) break;
        }

        SetInteractable(true);
        selectManager.RefreshCards();
        RefreshUI();

        if (!failed)
            Debug.Log($"[SongDetailPanel] '{currentSong.title}' 전체 다운로드 완료");
    }

    // ── 삭제 ─────────────────────────────────────────────────

    private void OnDeleteClicked()
    {
        downloadManager.DeleteSong(currentSong.id);
        SongLibrary.Instance.MarkSongRemoved(currentSong.id);
        selectedDifficulty = null;
        selectManager.RefreshCards();
        RefreshUI();
    }

    // ── 플레이 ───────────────────────────────────────────────

    private void OnPlayClicked()
    {
        GameSession.SelectedSong       = currentSong;
        GameSession.SelectedDifficulty = selectedDifficulty;
        SceneManager.LoadScene(gameSceneName);
    }

    // ── 유틸 ─────────────────────────────────────────────────

    private void SetInteractable(bool value)
    {
        downloadButton.interactable = value;
        deleteButton.interactable   = value;
        playButton.interactable     = value && selectedDifficulty != null;
        foreach (var (_, getBtn) in diffSlots)
            getBtn(this).interactable = value;
    }

    private static string FormatDuration(int seconds)
        => $"{seconds / 60}:{seconds % 60:D2}";
}
