package main

import (
	"fmt"
	"net/http"
	"os"
	"woke/api"
	"woke/db"
	"woke/player"
	"woke/scheduler"
	"woke/ui"

	tea "github.com/charmbracelet/bubbletea"
)

const helpText = `woke - TUI alarm clock with REST API

Usage:
  woke           Start the TUI (API server runs on :9119 in host mode)
  woke --help    Show this help

Modes:
  Host mode (default): Uses local SQLite, exposes REST API on :9119
  Client mode: Connects to remote woke server, syncs alarms, fires locally

  Configure mode in Settings (press 'c'):
    - Server URL: empty = host mode, or http://host:9119 for client mode
    - Server pass: password to authenticate with remote server
    - API password: password required for incoming API requests (host mode)
    - Poll seconds: how often client polls server for alarm updates

API endpoints (http://localhost:9119):

  List alarms:
    curl http://localhost:9119/api/alarms

  Get alarm:
    curl http://localhost:9119/api/alarms/1

  Create alarm (one-shot):
    curl -X POST http://localhost:9119/api/alarms \
      -H 'Content-Type: application/json' \
      -d '{"name": "Standup", "time": "09:00", "trigger": "once"}'

  Create alarm (cron, weekdays at 7:30):
    curl -X POST http://localhost:9119/api/alarms \
      -H 'Content-Type: application/json' \
      -d '{"name": "Morning", "time": "07:30", "trigger": "30 7 * * 1-5"}'

  Update alarm:
    curl -X PUT http://localhost:9119/api/alarms/1 \
      -H 'Content-Type: application/json' \
      -d '{"name": "New name", "time": "08:00"}'

  Toggle alarm on/off:
    curl -X PATCH http://localhost:9119/api/alarms/1/toggle

  Delete alarm:
    curl -X DELETE http://localhost:9119/api/alarms/1

  With authentication (if API password is set):
    curl -H 'Authorization: Bearer yourpassword' http://localhost:9119/api/alarms

TUI keybindings:
  j/k        Navigate alarms
  a          Add alarm
  e          Edit alarm
  d          Delete alarm
  space      Toggle enabled
  c          Settings
  q          Quit
`

func main() {
	if len(os.Args) > 1 && (os.Args[1] == "--help" || os.Args[1] == "-h") {
		fmt.Print(helpText)
		os.Exit(0)
	}

	// Always open local store for settings
	store, err := db.Open()
	if err != nil {
		fmt.Fprintf(os.Stderr, "Failed to open database: %v\n", err)
		os.Exit(1)
	}
	defer store.Close()

	settings := store.LoadSettings()
	clientMode := settings.ServerURL != ""

	// Determine alarm store: local DB or remote API
	var alarmStore db.AlarmStore
	if clientMode {
		alarmStore = api.NewClient(settings.ServerURL, settings.ServerPassword)
		fmt.Fprintf(os.Stderr, "Client mode: connecting to %s\n", settings.ServerURL)
	} else {
		alarmStore = store
	}

	pl := player.New()
	sched := scheduler.New(alarmStore, clientMode)
	sched.Start()
	defer sched.Stop()

	model := ui.NewModel(store, alarmStore, sched, pl, clientMode)
	p := tea.NewProgram(model, tea.WithAltScreen())

	// Start HTTP API server only in host mode
	if !clientMode {
		srv := api.New(store, settings.APIPassword, func() { p.Send(ui.AlarmsChangedMsg{}) })
		go func() {
			addr := ":9119"
			fmt.Fprintf(os.Stderr, "API server listening on %s\n", addr)
			if err := http.ListenAndServe(addr, srv.Handler()); err != nil {
				fmt.Fprintf(os.Stderr, "API server error: %v\n", err)
			}
		}()
	}

	if _, err := p.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}
}
