//
//  ContentView.swift
//  MSG Desktop
//
//  Created by Chad Nelson on 3/8/25.
//

import SwiftUI

struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = nextValue()
    }
}

struct ContentView: View {
    @ObservedObject var appState = AppState.shared
    private let maxLines = 300
    @State private var showCancelButton: Bool = false
    @State private var showReinitPopup = false
    @State private var showCancelPopup = false
    @State private var imageHeight: CGFloat = 0

    var body: some View {
        GeometryReader { geometry in
            VStack(spacing: 10) {
                // App icon
                let appIcon = NSImage(named: NSImage.applicationIconName)
                Image(nsImage: appIcon ?? NSImage())
                    .resizable()
                    .scaledToFit()
                    .frame(maxHeight: 150)
                    .background(
                        GeometryReader { proxy in
                            Color.clear
                                .preference(key: ViewHeightKey.self, value: proxy.size.height)
                        }
                    )
                    .onPreferenceChange(ViewHeightKey.self) { height in
                        self.imageHeight = height
                    }

                // ScrollView fills remaining height
                ScrollViewReader { proxy in
                    ScrollView {
                        VStack(alignment: .leading) {
                            TextEditor(text: $appState.output)
                                .font(.system(.body, design: .monospaced))
                                .frame(
                                    width: geometry.size.width - 60,
                                    height: max(0, geometry.size.height - imageHeight - 120) // - rough height of button row and padding
                                )
                                .padding()
                                .disabled(true)

                            Text("")
                                .id("bottom")
                        }
                    }
                    .onChange(of: appState.output) { _, _ in
                        trimLinesIfNeeded()
                        withAnimation {
                            proxy.scrollTo("bottom", anchor: .bottom)
                        }
                    }
                }

                // Buttons
                HStack {
                    Button("Init") {
                        DispatchQueue.main.async { self.showCancelButton = true }
                        runShellCommandAsync(command: "msg machine init", outputText: $appState.output, showButton: $showCancelButton)
                    }

                    Button("Reinit") {
                        showReinitPopup.toggle()
                    }
                    .confirmationDialog("Are you sure?", isPresented: $showReinitPopup, titleVisibility: .visible) {
                        Button("Confirm", role: .destructive) {
                            self.showCancelButton = true
                            runShellCommandAsync(command: "rm -rf ~/.guix && msg machine init", outputText: $appState.output, showButton: $showCancelButton)
                        }
                        Button("Cancel", role: .cancel) {}
                    }

                    Button("Start") {
                        runShellCommandAsync(command: "msg machine start", outputText: $appState.output, showButton: nil)
                    }

                    if showCancelButton {
                        Button("Cancel") {
                            showCancelPopup.toggle()
                        }
                        .confirmationDialog("Are you sure?", isPresented: $showCancelPopup, titleVisibility: .visible) {
                            Button("Confirm", role: .destructive) {
                                runShellCommandAsync(command: "kill $(ps aux | grep '[g]uile' | awk '{print $2}')", outputText: $appState.output, showButton: nil)
                                runShellCommandAsync(command: "kill $(ps aux | grep '[q]emu' | awk '{print $2}')", outputText: $appState.output, showButton: nil)
                                DispatchQueue.main.async {
                                    self.showCancelButton = false
                                }
                            }
                            Button("Cancel", role: .cancel) {}
                        }
                    }

                    if !showCancelButton {
                        Button("Stop") {
                            runShellCommandAsync(command: "msg machine stop", outputText: $appState.output, showButton: nil)
                        }
                    }

                    Button("Shell") {
                        runShellCommandAsync(
                            command: "osascript -e 'tell application \"Terminal\" to do script \"msg shell\"' -e 'tell application \"Terminal\" to activate'",
                            outputText: $appState.output,
                            showButton: nil
                        )
                    }
                }
            }
            .padding()
            .frame(maxHeight: .infinity)
            // Removed fixed frame here to allow dynamic window sizing
        }
    }

    private func trimLinesIfNeeded() {
        let lines = AppState.shared.output.split(separator: "\n")
        if lines.count > maxLines {
            let trimmedLines = lines.suffix(maxLines)
            AppState.shared.output = trimmedLines.joined(separator: "\n")
        }
    }
}

#Preview {
    ContentView()
}
