"""Small JSON playlist store in the user's application-data directory."""

from __future__ import annotations

import json
from pathlib import Path

from PySide6.QtCore import QStandardPaths


class PlaylistStore:
    def __init__(self, *, persistent: bool = True) -> None:
        self.persistent = bool(persistent)
        base = QStandardPaths.writableLocation(
            QStandardPaths.StandardLocation.AppDataLocation
        )
        self.directory = Path(base)
        self.path = self.directory / "playlists.json"
        roaming_root = self.directory.parent.parent
        self.legacy_directories = (
            roaming_root / "tauyori" / "MusicGridStudio",
            roaming_root / "Harmonia" / "Harmonia Player",
        )
        self.legacy_paths = tuple(
            directory / "playlists.json"
            for directory in self.legacy_directories
        )
        self.legacy_path = self.legacy_paths[-1]
        self.playlists: dict[str, list[str | dict]] = {"再生キュー": []}
        if self.persistent:
            self.load()

    def load(self) -> None:
        if not getattr(self, "persistent", True):
            self.playlists = {"再生キュー": []}
            return
        source_path = self.path
        if not source_path.is_file():
            source_path = next(
                (
                    legacy_path
                    for legacy_path in self.legacy_paths
                    if legacy_path.is_file()
                ),
                self.path,
            )
        loaded = False
        try:
            data = json.loads(source_path.read_text(encoding="utf-8"))
            playlists = data.get("playlists", {})
            if isinstance(playlists, dict):
                cleaned: dict[str, list[str | dict]] = {}
                for name, entries in playlists.items():
                    if not isinstance(entries, list):
                        continue
                    cleaned_entries: list[str | dict] = []
                    for entry in entries:
                        if isinstance(entry, str):
                            cleaned_entries.append(entry)
                        elif (
                            isinstance(entry, dict)
                            and entry.get("kind") == "cue_track"
                            and isinstance(entry.get("path"), str)
                        ):
                            cleaned_entries.append(dict(entry))
                    cleaned[str(name)] = cleaned_entries
                self.playlists = cleaned or {"再生キュー": []}
                loaded = True
        except (OSError, ValueError, TypeError):
            self.playlists = {"再生キュー": []}
        if "再生キュー" not in self.playlists:
            self.playlists = {"再生キュー": [], **self.playlists}
        if loaded and source_path != self.path:
            try:
                self.save()
            except OSError:
                pass

    def save(self) -> None:
        if not getattr(self, "persistent", True):
            return
        self.directory.mkdir(parents=True, exist_ok=True)
        temporary = self.path.with_suffix(".tmp")
        temporary.write_text(
            json.dumps(
                {"version": 2, "playlists": self.playlists},
                ensure_ascii=False,
                indent=2,
            ),
            encoding="utf-8",
        )
        temporary.replace(self.path)
