//
//  AppleMusicPickerViewController.swift
//  DashSmash
//
//  Lets the player search Apple Music and pick a song. The picked song is
//  passed to the TapTempoViewController so the player can tap-in the BPM
//  before the level starts.
//

import UIKit
import MusicKit

final class AppleMusicPickerViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate {

    private let searchBar = UISearchBar()
    private let tableView = UITableView(frame: .zero, style: .plain)
    private let backButton = UIButton(type: .system)
    private let titleLabel = UILabel()
    private let statusLabel = UILabel()
    private let activity = UIActivityIndicatorView(style: .medium)

    private var results: [Song] = []
    private var pendingSearchTask: Task<Void, Never>?
    private var authState: AppleMusicCoordinator.AuthorizationOutcome = .notDetermined

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .black
        setupUI()
        Task { await ensureAuthorized() }
    }

    override var prefersStatusBarHidden: Bool { true }

    private func setupUI() {
        titleLabel.text = "APPLE MUSIC"
        titleLabel.textColor = .white
        titleLabel.font = UIFont(name: "AvenirNext-Heavy", size: 22) ?? .boldSystemFont(ofSize: 22)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(titleLabel)

        backButton.setTitle("← Back", for: .normal)
        backButton.titleLabel?.font = UIFont(name: "AvenirNext-Medium", size: 17) ?? .systemFont(ofSize: 17)
        backButton.setTitleColor(.white, for: .normal)
        backButton.addTarget(self, action: #selector(backTapped), for: .touchUpInside)
        backButton.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(backButton)

        searchBar.placeholder = "Search song or artist"
        searchBar.barStyle = .black
        searchBar.searchBarStyle = .minimal
        searchBar.searchTextField.textColor = .white
        searchBar.delegate = self
        searchBar.returnKeyType = .search
        searchBar.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(searchBar)

        statusLabel.textColor = UIColor.white.withAlphaComponent(0.6)
        statusLabel.font = UIFont(name: "AvenirNext-Medium", size: 14) ?? .systemFont(ofSize: 14)
        statusLabel.textAlignment = .center
        statusLabel.numberOfLines = 0
        statusLabel.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(statusLabel)

        activity.color = .white
        activity.hidesWhenStopped = true
        activity.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activity)

        tableView.backgroundColor = .clear
        tableView.separatorColor = UIColor.white.withAlphaComponent(0.15)
        tableView.dataSource = self
        tableView.delegate = self
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        // Insert tableView BEHIND statusLabel/activity so empty-state text is
        // not obscured by the (otherwise transparent) empty table area.
        view.insertSubview(tableView, belowSubview: statusLabel)

        NSLayoutConstraint.activate([
            backButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
            backButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 12),

            titleLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            titleLabel.centerYAnchor.constraint(equalTo: backButton.centerYAnchor),

            searchBar.topAnchor.constraint(equalTo: backButton.bottomAnchor, constant: 8),
            searchBar.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8),
            searchBar.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8),

            tableView.topAnchor.constraint(equalTo: searchBar.bottomAnchor, constant: 8),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),

            statusLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            statusLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            statusLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 32),
            statusLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -32),

            activity.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            activity.topAnchor.constraint(equalTo: statusLabel.bottomAnchor, constant: 12)
        ])
    }

    private func ensureAuthorized() async {
        statusLabel.text = "Requesting Apple Music access…"
        let outcome = await AppleMusicCoordinator.shared.authorize()
        authState = outcome
        print("[DashSmash] MusicAuthorization result: \(outcome)")
        switch outcome {
        case .authorized:
            statusLabel.text = "Search for a song to play through."
            // If the user typed before authorization completed, run the search now.
            if let text = searchBar.text, !text.trimmingCharacters(in: .whitespaces).isEmpty {
                scheduleSearch(query: text, immediate: true)
            }
        case .denied:
            statusLabel.text = "Apple Music access denied.\nEnable it in Settings → Privacy → Media & Apple Music."
        case .restricted:
            statusLabel.text = "Apple Music is restricted on this device."
        case .notDetermined:
            statusLabel.text = "Apple Music permission was not granted."
        }
    }

    @objc private func backTapped() {
        navigationController?.popViewController(animated: true)
    }

    // MARK: - Searching

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        scheduleSearch(query: searchText)
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
        scheduleSearch(query: searchBar.text ?? "", immediate: true)
    }

    private func scheduleSearch(query: String, immediate: Bool = false) {
        pendingSearchTask?.cancel()
        let trimmed = query.trimmingCharacters(in: .whitespaces)
        guard !trimmed.isEmpty else {
            results = []
            tableView.reloadData()
            statusLabel.text = AppleMusicCoordinator.shared.isAuthorized
                ? "Search for a song to play through."
                : statusLabel.text
            return
        }
        // If we haven't yet been granted authorization, don't fire a request
        // that's guaranteed to fail — defer; ensureAuthorized() will re-trigger.
        guard authState == .authorized else {
            print("[DashSmash] Search deferred: not yet authorized (state=\(authState))")
            statusLabel.text = "Waiting for Apple Music permission…"
            return
        }
        pendingSearchTask = Task { [weak self] in
            if !immediate {
                try? await Task.sleep(nanoseconds: 350_000_000)
                if Task.isCancelled { return }
            }
            await self?.runSearch(trimmed)
        }
    }

    private func runSearch(_ query: String) async {
        statusLabel.text = nil
        activity.startAnimating()
        defer { activity.stopAnimating() }
        do {
            print("[DashSmash] Apple Music search: \(query)")
            let songs = try await AppleMusicCoordinator.shared.searchSongs(query: query, limit: 25)
            print("[DashSmash] Apple Music search returned \(songs.count) songs")
            results = songs
            tableView.reloadData()
            if songs.isEmpty {
                statusLabel.text = "No results for “\(query)”."
            }
        } catch {
            print("[DashSmash] Apple Music search failed: \(error)")
            statusLabel.text = "Search failed:\n\(error.localizedDescription)"
        }
    }

    // MARK: - Table

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        results.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let song = results[indexPath.row]
        cell.backgroundColor = .black
        cell.selectionStyle = .gray
        var config = UIListContentConfiguration.cell()
        config.text = song.title
        config.secondaryText = song.artistName
        config.textProperties.color = .white
        config.textProperties.font = UIFont(name: "AvenirNext-Bold", size: 16) ?? .boldSystemFont(ofSize: 16)
        config.secondaryTextProperties.color = UIColor.white.withAlphaComponent(0.6)
        config.secondaryTextProperties.font = UIFont(name: "AvenirNext-Medium", size: 13) ?? .systemFont(ofSize: 13)
        cell.contentConfiguration = config
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let song = results[indexPath.row]
        tableView.deselectRow(at: indexPath, animated: true)
        let tap = TapTempoViewController(track: .appleMusicCatalog(song))
        navigationController?.pushViewController(tap, animated: true)
    }
}
