import SwiftUI

struct PlayerBar: View {
    @Environment(AppState.self) private var app
    @AppStorage("skipDurationSeconds") private var skipSeconds: Int = 30
    @State private var scrubbing: Bool = false
    @State private var scrubValue: Double = 0

    var body: some View {
        if let item = app.currentItem {
            VStack(spacing: 0) {
                Divider()
                content(item: item)
                    .padding(.horizontal, 16)
                    #if os(iOS)
                    .padding(.top, 8)
                    .padding(.bottom, 10)
                    #else
                    .padding(.vertical, 10)
                    #endif
                    .background(.bar)
            }
            .transition(.move(edge: .bottom).combined(with: .opacity))
        } else if app.isPreparingPlayback {
            VStack(spacing: 0) {
                Divider()
                HStack(spacing: 12) {
                    ProgressView()
                    Text("Wiedergabe wird vorbereitet …").font(.subheadline).foregroundStyle(.secondary)
                    Spacer()
                }
                .padding(.horizontal, 16)
                .padding(.vertical, 14)
                .background(.bar)
            }
        }
    }

    // MARK: - Platform layouts

    #if os(iOS)
    @ViewBuilder
    private func content(item: LibraryItem) -> some View {
        VStack(spacing: 8) {
            // Header row: cover, title/author, play button
            HStack(spacing: 12) {
                cover(item: item)
                VStack(alignment: .leading, spacing: 2) {
                    Text(item.title).font(.subheadline).bold().lineLimit(1)
                    Text(item.author).font(.caption).foregroundStyle(.secondary).lineLimit(1)
                    if let err = app.player.errorMessage {
                        Text(err).font(.caption2).foregroundStyle(.red).lineLimit(1)
                    }
                }
                Spacer(minLength: 0)
                Button { app.togglePlay() } label: {
                    Image(systemName: app.player.isPlaying ? "pause.circle.fill" : "play.circle.fill")
                        .font(.system(size: 36))
                }
                .buttonStyle(.plain)
                .disabled(!app.player.isReady)
            }

            scrubber
            HStack(spacing: 24) {
                Button { app.skip(by: -Double(skipSeconds)) } label: {
                    Image(systemName: skipBackImage).font(.system(size: 22))
                }
                .buttonStyle(.plain)
                .disabled(!app.player.isReady)

                Button { app.skip(by: Double(skipSeconds)) } label: {
                    Image(systemName: skipForwardImage).font(.system(size: 22))
                }
                .buttonStyle(.plain)
                .disabled(!app.player.isReady)

                Spacer()

                rateMenu

                Button {
                    app.stopPlayback()
                } label: {
                    Image(systemName: "xmark.circle.fill")
                        .font(.system(size: 22))
                        .foregroundStyle(.secondary)
                }
                .buttonStyle(.plain)
            }
            .padding(.top, 2)
        }
    }
    #else
    @ViewBuilder
    private func content(item: LibraryItem) -> some View {
        HStack(spacing: 14) {
            cover(item: item)

            VStack(alignment: .leading, spacing: 2) {
                Text(item.title).font(.subheadline).bold().lineLimit(1)
                Text(item.author).font(.caption).foregroundStyle(.secondary).lineLimit(1)
                if let err = app.player.errorMessage {
                    Text(err).font(.caption2).foregroundStyle(.red).lineLimit(1)
                }
            }
            .frame(minWidth: 160, idealWidth: 200, maxWidth: 240, alignment: .leading)

            transportControls

            scrubber
                .frame(minWidth: 200)

            rateMenu

            Spacer(minLength: 0)

            statusIndicator

            Button {
                app.stopPlayback()
            } label: {
                Image(systemName: "xmark.circle.fill")
                    .foregroundStyle(.secondary)
            }
            .buttonStyle(.plain)
            .help("Wiedergabe beenden")
        }
    }

    private var transportControls: some View {
        HStack(spacing: 14) {
            Button { app.skip(by: -Double(skipSeconds)) } label: {
                Image(systemName: skipBackImage).font(.system(size: 18))
            }
            .buttonStyle(.plain)
            .disabled(!app.player.isReady)

            Button { app.togglePlay() } label: {
                Image(systemName: app.player.isPlaying ? "pause.circle.fill" : "play.circle.fill")
                    .font(.system(size: 34))
            }
            .buttonStyle(.plain)
            .disabled(!app.player.isReady)
            .keyboardShortcut(.space, modifiers: [])

            Button { app.skip(by: Double(skipSeconds)) } label: {
                Image(systemName: skipForwardImage).font(.system(size: 18))
            }
            .buttonStyle(.plain)
            .disabled(!app.player.isReady)
        }
    }

    private var statusIndicator: some View {
        HStack(spacing: 4) {
            Circle()
                .fill(app.network.isOnline ? .green : .orange)
                .frame(width: 6, height: 6)
            if app.sync.queuedCount > 0 {
                Text("\(app.sync.queuedCount)")
                    .font(.caption2)
                    .foregroundStyle(.secondary)
            }
        }
        .help(app.network.isOnline
              ? "Online – Fortschritt wird synchronisiert"
              : "Offline – \(app.sync.queuedCount) Eintrag/Einträge wartend")
    }
    #endif

    // MARK: - Shared subviews

    private func cover(item: LibraryItem) -> some View {
        Group {
            if let url = app.client.coverURL(itemId: item.id) {
                AsyncImage(url: url) { phase in
                    if let img = phase.image {
                        img.resizable().aspectRatio(contentMode: .fill)
                    } else {
                        Color.gray.opacity(0.3)
                    }
                }
            } else {
                Color.gray.opacity(0.3)
            }
        }
        #if os(iOS)
        .frame(width: 44, height: 44)
        #else
        .frame(width: 48, height: 48)
        #endif
        .clipShape(RoundedRectangle(cornerRadius: 6))
    }

    private var scrubber: some View {
        VStack(spacing: 2) {
            Slider(
                value: Binding(
                    get: { scrubbing ? scrubValue : app.player.absoluteCurrentTime },
                    set: { scrubValue = $0; scrubbing = true }
                ),
                in: 0...max(app.player.totalDuration, 1),
                onEditingChanged: { editing in
                    if !editing {
                        app.seekAbsolute(scrubValue)
                        scrubbing = false
                    }
                }
            )
            .disabled(!app.player.isReady)
            HStack {
                Text(formatTime(scrubbing ? scrubValue : app.player.absoluteCurrentTime))
                    .font(.caption2.monospacedDigit())
                    .foregroundStyle(.secondary)
                Spacer()
                Text(formatTime(app.player.totalDuration))
                    .font(.caption2.monospacedDigit())
                    .foregroundStyle(.secondary)
            }
        }
    }

    private var rateMenu: some View {
        Menu {
            ForEach([0.75, 1.0, 1.25, 1.5, 1.75, 2.0], id: \.self) { r in
                Button {
                    app.setRate(Float(r))
                } label: {
                    HStack {
                        Text(String(format: "%.2g×", r))
                        if abs(Double(app.player.rate) - r) < 0.01 {
                            Image(systemName: "checkmark")
                        }
                    }
                }
            }
        } label: {
            Text(String(format: "%.2g×", Double(app.player.rate)))
                .font(.caption.monospacedDigit())
                .padding(.horizontal, 10).padding(.vertical, 5)
                .overlay(Capsule().stroke(Color.secondary.opacity(0.4)))
        }
        #if os(macOS)
        .menuStyle(.borderlessButton)
        .fixedSize()
        .help("Geschwindigkeit")
        #endif
    }

    private var skipForwardImage: String {
        switch skipSeconds {
        case ...10: return "goforward.10"
        case 11...15: return "goforward.15"
        case 16...30: return "goforward.30"
        case 31...45: return "goforward.45"
        case 46...60: return "goforward.60"
        default: return "goforward.90"
        }
    }

    private var skipBackImage: String {
        switch skipSeconds {
        case ...10: return "gobackward.10"
        case 11...15: return "gobackward.15"
        case 16...30: return "gobackward.30"
        case 31...45: return "gobackward.45"
        case 46...60: return "gobackward.60"
        default: return "gobackward.90"
        }
    }

    private func formatTime(_ seconds: Double) -> String {
        guard seconds.isFinite, seconds >= 0 else { return "0:00" }
        let total = Int(seconds)
        let h = total / 3600
        let m = (total % 3600) / 60
        let s = total % 60
        if h > 0 {
            return String(format: "%d:%02d:%02d", h, m, s)
        }
        return String(format: "%d:%02d", m, s)
    }
}
