package main

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	encrypt "fckeuspy-go/lib"
	"html/template"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/widget"
)

var (
	priv    *rsa.PrivateKey
	pubPEM  []byte
	certPEM []byte // self-signed cert jen pro sdílení identity (volitelné)
	tmpl    *template.Template
)

type envelope struct {
	// Encrypted AES key, Nonce, Ciphertext (GCM)
	EK string `json:"ek"` // base64(RSA-OAEP(aesKey))
	N  string `json:"n"`  // base64(nonce 12B)
	CT string `json:"ct"` // base64(GCM(ciphertext||tag))
}

func main() {
	if err := rootCmd.Execute(); err != nil {
		log.Printf("Chyba: %v", err)
		os.Exit(1)
	}
	// Malé zpoždění pro případné async logy
	time.Sleep(50 * time.Millisecond)
}

func runFyne() {
	storageDir, w := NewUI()
	vaultPath := filepath.Join(storageDir, "vault.enc")
	placeholder := widget.NewLabel("Inicializace trezoru…")
	w.SetContent(placeholder)

	showDialog := func() {
		ShowPasswordVaultDialog(w, vaultPath, func(create bool, password string, commonName string) {
			if password == "" { // Cancel nebo zavření dialogu => ukonči app
				fyne.CurrentApp().Quit()
				return
			}
			var store encrypt.SecureJSONStore
			var err error
			if create {
				store, err = encrypt.CreateEncryptedStore(vaultPath, password, true, commonName)
			} else {
				store, err = encrypt.OpenEncryptedStore(vaultPath, password)
				if err != nil {
					dialog.NewError(err, w).Show()
					return
				}
			}
			if err != nil {
				dialog.NewError(err, w).Show()
				return
			}
			vs, err := NewVaultService(store)
			if err != nil {
				dialog.NewError(err, w).Show()
				return
			}
			parts := buildEntries()
			fyne.CurrentApp().Driver().AllWindows()[0].SetTitle("Encryptor (Vault)")
			w.SetContent(buildTabbedUI(parts, vs, vaultPath))
		})
	}

	// Pokud soubor neexistuje, dialog v režimu vytvořit (default). Pokud existuje, uživatel může přepnout.
	showDialog()
	w.ShowAndRun()
}

func RunWebApp() {
	// Otevři nebo vytvoř šifrovaný trezor a načti identitu pouze z něj
	vaultPath := os.Getenv("VAULT_PATH")
	if vaultPath == "" {
		vaultPath = "./vault.enc"
	}
	pw := os.Getenv("VAULT_PASSWORD")
	if pw == "" {
		log.Fatal("VAULT_PASSWORD must be set for web mode")
	}
	var store encrypt.SecureJSONStore
	if _, statErr := os.Stat(vaultPath); os.IsNotExist(statErr) {
		s, err := encrypt.CreateEncryptedStore(vaultPath, pw, true, "")
		if err != nil {
			log.Fatal(err)
		}
		store = s
	} else {
		s, err := encrypt.OpenEncryptedStore(vaultPath, pw)
		if err != nil {
			log.Fatal(err)
		}
		store = s
	}
	// Načti privátní klíč a veřejné materiály
	privPEM := store.IdentityPrivatePEM()
	if privPEM == "" {
		log.Fatal("missing private key in vault")
	}
	block, _ := pem.Decode([]byte(privPEM))
	if block == nil || block.Type != "RSA PRIVATE KEY" {
		log.Fatal("invalid private key PEM in vault")
	}
	key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		log.Fatal(err)
	}
	priv = key
	pubPEM = []byte(store.IdentityPublicPEM())
	certPEM = []byte(store.IdentityCertPEM())

	// 2) šablony
	tmpl = template.Must(template.ParseGlob("templates/*.html"))

	muxServer := NewServer()
	log.Fatal(http.ListenAndServe(":8080", muxServer))
}
