import SwiftUI
import UniformTypeIdentifiers

struct RoomsPanel: View {
    @ObservedObject var model: AppModel

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            PanelTitle("Rooms", icon: "radio")
            if model.channels.isEmpty {
                EmptyLine("No rooms loaded")
            } else {
                ForEach(model.channels) { channel in
                    HStack(spacing: 10) {
                        VStack(alignment: .leading, spacing: 4) {
                            HStack {
                                Text(channel.name)
                                    .font(Theme.headlineFont)
                                    .foregroundStyle(Theme.text)
                                if channel.isDefault {
                                    Text("DEFAULT")
                                        .font(Theme.microFont)
                                        .foregroundStyle(Theme.background)
                                        .padding(.horizontal, 6)
                                        .padding(.vertical, 2)
                                        .background(Theme.amber)
                                        .clipShape(RoundedRectangle(cornerRadius: Theme.smallCorner))
                                }
                            }
                            Text(channel.description.isEmpty ? "\(channel.trackCount) tracks" : channel.description)
                                .font(Theme.captionFont)
                                .foregroundStyle(Theme.muted)
                            Text("\(channel.listenerCount) listener(s)")
                                .font(Theme.mono(12))
                                .foregroundStyle(Theme.ready)
                        }
                        Spacer()
                        Button {
                            Task { await model.joinChannel(channel.id) }
                        } label: {
                            Image(systemName: model.currentChannelId == channel.id ? "checkmark.circle.fill" : "dot.radiowaves.left.and.right")
                                .frame(width: 44, height: 38)
                        }
                        .buttonStyle(.borderedProminent)
                        .tint(model.currentChannelId == channel.id ? Theme.ready : Theme.accent)
                    }
                    .rowStyle(isActive: model.currentChannelId == channel.id)
                }
            }
        }
        .panel()
    }
}

struct QueuePanel: View {
    @ObservedObject var model: AppModel

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            PanelTitle("Queue", icon: "list.bullet")
            if model.queue.isEmpty {
                EmptyLine(model.queueLoaded ? "Queue is empty" : "Queue not loaded")
            } else {
                ForEach(Array(model.queue.prefix(80).enumerated()), id: \.offset) { index, track in
                    TrackLine(
                        track: track,
                        isActive: index == model.currentIndex,
                        subtitle: "#\(index + 1) \(formatDuration(track.duration))"
                    ) {
                        Button {
                            model.jumpToQueueIndex(index)
                        } label: {
                            Image(systemName: "play.fill")
                                .frame(width: 38, height: 34)
                        }
                        .buttonStyle(.bordered)

                        Button(role: .destructive) {
                            Task { await model.removeQueueIndex(index) }
                        } label: {
                            Image(systemName: "trash")
                                .frame(width: 38, height: 34)
                        }
                        .buttonStyle(.bordered)
                    }
                }
            }
        }
        .panel()
    }
}

struct PeoplePanel: View {
    @ObservedObject var model: AppModel

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            PanelTitle("People", icon: "person.2")
            if model.listeners.isEmpty {
                EmptyLine("No listener names in this room yet")
            } else {
                ForEach(model.listeners, id: \.self) { listener in
                    HStack {
                        Image(systemName: listener == model.currentUser?.username ? "person.fill.checkmark" : "person.fill")
                            .foregroundStyle(listener == model.currentUser?.username ? Theme.ready : Theme.muted)
                        Text(listener)
                            .foregroundStyle(Theme.text)
                        Spacer()
                        if listener == model.currentUser?.username {
                            Text("YOU")
                                .font(Theme.microFont)
                                .foregroundStyle(Theme.ready)
                        }
                    }
                    .rowStyle(isActive: listener == model.currentUser?.username)
                }
            }
        }
        .panel()
    }
}

struct LibraryPanel: View {
    @ObservedObject var model: AppModel
    @State private var query = ""
    @State private var fetchURL = ""
    @State private var fileImporterPresented = false

    var matches: [Track] {
        let trimmed = query.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
        let base = model.libraryTracks
        if trimmed.isEmpty {
            return Array(base.prefix(80))
        }
        return Array(base.filter {
            $0.title.lowercased().contains(trimmed) ||
            $0.filename.lowercased().contains(trimmed) ||
            ($0.artist ?? "").lowercased().contains(trimmed)
        }.prefix(80))
    }

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            PanelTitle("Library", icon: "music.note.list")
            importTools
            HStack(spacing: 8) {
                Image(systemName: "magnifyingglass")
                    .foregroundStyle(Theme.muted)
                TextField("Search tracks", text: $query)
                    .textInputAutocapitalization(.never)
                    .autocorrectionDisabled()
                    .foregroundStyle(Theme.text)
            }
            .padding(10)
            .background(Theme.panel2)
            .clipShape(RoundedRectangle(cornerRadius: Theme.corner))

            if !model.libraryLoaded {
                EmptyLine("Loading library")
            } else if matches.isEmpty {
                EmptyLine("No matching tracks")
            } else {
                ForEach(matches) { track in
                    TrackLine(
                        track: track,
                        isActive: model.sourceMode == .library && model.currentTrackId == track.id,
                        subtitle: track.artist ?? track.filename
                    ) {
                        Button {
                            model.playLibraryTrack(track)
                        } label: {
                            Image(systemName: "play.fill")
                                .frame(width: 38, height: 34)
                        }
                        .buttonStyle(.borderedProminent)
                        .tint(Theme.accent)

                        Menu {
                            Button("Add to Queue") {
                                Task { await model.queueTrack(track, playNext: false) }
                            }
                            Button("Play Next") {
                                Task { await model.queueTrack(track, playNext: true) }
                            }
                        } label: {
                            Image(systemName: "plus")
                                .frame(width: 38, height: 34)
                        }
                        .buttonStyle(.bordered)
                    }
                }
            }
        }
        .panel()
        .fileImporter(
            isPresented: $fileImporterPresented,
            allowedContentTypes: [.audio, .movie],
            allowsMultipleSelection: true
        ) { result in
            switch result {
            case .success(let urls):
                Task { await model.uploadFiles(urls) }
            case .failure(let error):
                model.importStatus = "File picker failed: \(error.localizedDescription)"
            }
        }
    }

    private var importTools: some View {
        VStack(alignment: .leading, spacing: 10) {
            HStack(spacing: 8) {
                Button {
                    fileImporterPresented = true
                } label: {
                    Label(model.isUploading ? "Uploading" : "Upload Files", systemImage: "square.and.arrow.up")
                        .frame(maxWidth: .infinity)
                }
                .buttonStyle(.borderedProminent)
                .tint(Theme.accent)
                .disabled(model.isUploading)

                Button {
                    Task { await model.loadLibrary() }
                } label: {
                    Image(systemName: "arrow.clockwise")
                        .frame(width: 42, height: 34)
                }
                .buttonStyle(.bordered)
                .accessibilityLabel("Reload Library")
            }

            HStack(spacing: 8) {
                Image(systemName: "link")
                    .foregroundStyle(Theme.muted)
                TextField("Fetch from website URL", text: $fetchURL)
                    .textInputAutocapitalization(.never)
                    .autocorrectionDisabled()
                    .keyboardType(.URL)
                    .foregroundStyle(Theme.text)
                Button {
                    Task { await model.fetchFromWebsite(fetchURL) }
                } label: {
                    Image(systemName: model.isFetching ? "hourglass" : "arrow.down.circle")
                        .frame(width: 40, height: 34)
                }
                .buttonStyle(.bordered)
                .disabled(model.isFetching)
                .accessibilityLabel("Fetch URL")
            }
            .padding(10)
            .background(Theme.panel2)
            .clipShape(RoundedRectangle(cornerRadius: Theme.corner))

            if let playlist = model.pendingFetchPlaylist {
                VStack(alignment: .leading, spacing: 8) {
                    Text("Playlist found")
                        .font(Theme.mono(12, weight: .bold))
                        .foregroundStyle(Theme.amber)
                    Text("\(playlist.title) · \(playlist.count) items")
                        .font(Theme.pixel(16, weight: .semibold))
                        .foregroundStyle(Theme.text)
                        .lineLimit(2)
                    HStack(spacing: 8) {
                        Button {
                            Task { await model.confirmFetchPlaylist() }
                        } label: {
                            Label("Queue Playlist", systemImage: "checkmark.circle")
                                .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.borderedProminent)
                        .tint(Theme.ready)
                        .disabled(model.isFetching)

                        Button {
                            model.cancelFetchPlaylist()
                        } label: {
                            Label("Cancel", systemImage: "xmark")
                                .frame(maxWidth: .infinity)
                        }
                        .buttonStyle(.bordered)
                    }
                }
                .padding(10)
                .background(Theme.panel2)
                .clipShape(RoundedRectangle(cornerRadius: Theme.corner))
            }

            if !model.importStatus.isEmpty {
                Text(model.importStatus)
                    .font(Theme.mono(12))
                    .foregroundStyle(Theme.muted)
                    .lineLimit(2)
            }
        }
    }
}

struct PlaylistsPanel: View {
    @ObservedObject var model: AppModel

    var body: some View {
        VStack(alignment: .leading, spacing: 12) {
            PanelTitle("Playlists", icon: "rectangle.stack")
            if model.allPlaylists.isEmpty {
                EmptyLine(model.playlistsLoaded ? "No playlists" : "Loading playlists")
            } else {
                ScrollView(.horizontal, showsIndicators: false) {
                    HStack(spacing: 8) {
                        ForEach(model.allPlaylists.prefix(40)) { playlist in
                            let isSelected = model.selectedPlaylistId == playlist.id
                            Button {
                                Task { await model.loadPlaylist(playlist.id) }
                            } label: {
                                VStack(alignment: .leading, spacing: 4) {
                                    Text(playlist.name)
                                        .font(Theme.pixel(16, weight: .bold))
                                        .foregroundStyle(isSelected ? Theme.background : Theme.text)
                                        .lineLimit(1)
                                    Text("\(playlist.trackIds.count) tracks")
                                        .font(Theme.mono(12))
                                        .foregroundStyle(isSelected ? Theme.background.opacity(0.72) : Theme.muted)
                                }
                                .frame(width: 150, alignment: .leading)
                                .padding(10)
                            }
                            .buttonStyle(.plain)
                            .background(isSelected ? Theme.accent : Theme.panel2)
                            .overlay(
                                RoundedRectangle(cornerRadius: Theme.corner)
                                    .stroke(isSelected ? Theme.text : Theme.stroke.opacity(0.38), lineWidth: 1)
                            )
                            .clipShape(RoundedRectangle(cornerRadius: Theme.corner))
                        }
                    }
                }
            }

            if let playlist = model.selectedPlaylist {
                HStack {
                    VStack(alignment: .leading, spacing: 3) {
                        Text(playlist.name)
                            .font(Theme.headlineFont)
                            .foregroundStyle(Theme.text)
                        Text(playlist.ownerName.isEmpty ? "\(playlist.trackIds.count) tracks" : "by \(playlist.ownerName)")
                            .font(Theme.captionFont)
                            .foregroundStyle(Theme.muted)
                    }
                    Spacer()
                    Button {
                        Task { await model.addPlaylistToQueue(playlist, playNext: false) }
                    } label: {
                        Image(systemName: "text.badge.plus")
                            .frame(width: 38, height: 34)
                    }
                    .buttonStyle(.bordered)
                    Button {
                        Task { await model.addPlaylistToQueue(playlist, playNext: true) }
                    } label: {
                        Image(systemName: "text.line.first.and.arrowtriangle.forward")
                            .frame(width: 38, height: 34)
                    }
                    .buttonStyle(.bordered)
                }

                ForEach(Array(playlist.trackIds.prefix(80).enumerated()), id: \.offset) { index, trackId in
                    let track = model.track(for: trackId) ?? Track(id: trackId, filename: trackId, title: trackId, duration: 0)
                    TrackLine(
                        track: track,
                        isActive: model.currentTrackId == track.id,
                        subtitle: "#\(index + 1)"
                    ) {
                        Button {
                            Task { await model.queueTrack(track, playNext: false) }
                        } label: {
                            Image(systemName: "plus")
                                .frame(width: 38, height: 34)
                        }
                        .buttonStyle(.bordered)
                        Button {
                            Task { await model.queueTrack(track, playNext: true) }
                        } label: {
                            Image(systemName: "arrow.up.to.line")
                                .frame(width: 38, height: 34)
                        }
                        .buttonStyle(.bordered)
                    }
                }
            }
        }
        .panel()
    }
}

struct DebugPanel: View {
    @ObservedObject var model: AppModel

    var body: some View {
        VStack(alignment: .leading, spacing: 10) {
            PanelTitle("Diagnostics", icon: "waveform.path.ecg")
            debugRow("Server", model.serverURL)
            debugRow("Auth", model.authState.rawValue)
            debugRow("User", model.currentUser?.username ?? "-")
            debugRow("Room", model.currentChannelId ?? "-")
            debugRow("Track", model.currentTrackId ?? "-")
            debugRow("Expected", "\(model.expectedPositionMs)ms")
            debugRow("Player", "\(model.playerPositionMs)ms")
            debugRow("Drift", "\(model.driftMs)ms")
            Divider().overlay(Theme.stroke)
            ForEach(model.debugEvents, id: \.self) { event in
                Text(event)
                    .font(Theme.mono(12))
                    .foregroundStyle(Theme.muted)
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
        }
        .panel()
    }

    private func debugRow(_ label: String, _ value: String) -> some View {
        HStack(alignment: .top) {
            Text(label)
                .foregroundStyle(Theme.muted)
                .frame(width: 78, alignment: .leading)
            Text(value)
                .foregroundStyle(Theme.text)
                .textSelection(.enabled)
            Spacer(minLength: 0)
        }
        .font(Theme.mono(12))
    }
}
