package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

var (
	token    = flag.String("token", "", "JWT token for authentication (get from browser DevTools)")
	room     = flag.String("room", "", "Room ID to join (e.g., @hyperspaceout)")
	email    = flag.String("email", "", "Email for login (requires --password, not yet implemented)")
	password = flag.String("password", "", "Password for login (requires --email, not yet implemented)")
)

func main() {
	flag.Parse()

	// Validate required flags
	if *room == "" {
		log.Fatal("Error: --room is required")
	}

	// Get authentication token
	authToken, err := GetToken(*token, *email, *password)
	if err != nil {
		log.Fatalf("Authentication error: %v", err)
	}

	// Create client
	client := NewKosmiClient(authToken, *room)

	// Set up message handler to print incoming messages
	client.SetMessageHandler(func(msg Message) {
		timestamp := formatTime(msg.Time)
		fmt.Printf("\r[%s] %s: %s\n> ", timestamp, msg.DisplayName, msg.Body)
	})

	// Connect to Kosmi
	if err := client.Connect(); err != nil {
		log.Fatalf("Connection error: %v", err)
	}

	// Set up graceful shutdown
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

	// Start goroutine to handle shutdown signal
	shutdownChan := make(chan struct{})
	go func() {
		<-sigChan
		fmt.Println("\n\nReceived interrupt signal, shutting down gracefully...")
		close(shutdownChan)
	}()

	// Print usage instructions
	fmt.Println("\n" + strings.Repeat("=", 60))
	fmt.Println("Connected! Type messages and press Enter to send.")
	fmt.Println("Press Ctrl+C to exit.")
	fmt.Println(strings.Repeat("=", 60) + "\n")

	// Start interactive CLI loop
	go func() {
		scanner := bufio.NewScanner(os.Stdin)
		fmt.Print("> ")
		
		for scanner.Scan() {
			select {
			case <-shutdownChan:
				return
			default:
			}

			text := strings.TrimSpace(scanner.Text())
			
			// Skip empty messages
			if text == "" {
				fmt.Print("> ")
				continue
			}

			// Handle special commands
			if text == "/quit" || text == "/exit" {
				fmt.Println("Exiting...")
				close(shutdownChan)
				return
			}

			if text == "/help" {
				printHelp()
				fmt.Print("> ")
				continue
			}

			// Send the message
			if err := client.SendMessage(text); err != nil {
				fmt.Printf("\rError sending message: %v\n> ", err)
			} else {
				// Clear the line and reprint prompt
				fmt.Print("> ")
			}
		}

		if err := scanner.Err(); err != nil {
			log.Printf("Scanner error: %v", err)
		}
	}()

	// Wait for shutdown signal
	<-shutdownChan

	// Close the client gracefully
	if err := client.Close(); err != nil {
		log.Printf("Error closing client: %v", err)
	}

	// Give a moment for cleanup
	time.Sleep(200 * time.Millisecond)
	
	fmt.Println("Goodbye!")
}

// formatTime converts ISO timestamp to readable format
func formatTime(isoTime string) string {
	t, err := time.Parse(time.RFC3339, isoTime)
	if err != nil {
		return isoTime
	}
	return t.Format("15:04:05")
}

// printHelp displays available commands
func printHelp() {
	fmt.Println("\nAvailable commands:")
	fmt.Println("  /help  - Show this help message")
	fmt.Println("  /quit  - Exit the client")
	fmt.Println("  /exit  - Exit the client")
	fmt.Println("\nJust type any text and press Enter to send a message.")
}

