//
//  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
                    }
                
                ZStack {
                    Color.black
                        .ignoresSafeArea()
                    
                    // ScrollView fills remaining height
                    ScrollViewReader { proxy in
                        ScrollView {
                            LazyVStack(alignment: .leading, spacing: 0) {
                                let lines = appState.output.components(separatedBy: .newlines)
                                
                                ForEach(lines.indices, id: \.self) { index in
                                    Text(lines[index])
                                        .font(.system(.body, design: .monospaced))
                                        .foregroundColor(.gray)
                                        .frame(maxWidth: .infinity, alignment: .leading)
                                    
                                }
                                
                                Color.clear.frame(height: 1).id("bottom")
                            }
                            .padding()
                        }
                        .onChange(of: appState.output) { _, _ in
                            trimLinesIfNeeded()
                            withAnimation {
                                proxy.scrollTo("bottom", anchor: .bottom)
                            }
                        }
                        
                        //                    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)
            .onAppear {
                // Silences error due to metallib on resizing of window
                let device = MTLCreateSystemDefaultDevice()
                _ = device?.makeDefaultLibrary()
            }
        }
    }

    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()
}