package main

import (
	"fmt"
	"net/url"

	"git.koval.net/cyclane/cctv/server/ingest"
	"git.koval.net/cyclane/cctv/server/models"
	"github.com/pocketbase/pocketbase/core"
	"golang.org/x/sync/errgroup"
)

func handleCameraUpdate(e *core.RecordEvent) error {
	if e.Record.Collection().Name != "cameras" {
		return e.Next()
	}
	camera := &models.Camera{}
	camera.SetProxyRecord(e.Record)
	log := e.App.Logger().With("camera", camera.Id)

	// Encrypt password
	password := camera.PasswordRaw()
	log.Info("Old password", "password", password)
	if err := camera.SetPassword(password, e.App.EncryptionEnv()); err != nil {
		return fmt.Errorf("failed to encrypt password: %w", err)
	}
	log.Info("New password", "password", camera.PasswordRaw())

	onvifProfiles, err := ingest.GetOnvifProfiles(e.Context, camera.OnvifHost(), camera.Username(), password)
	if err != nil {
		return fmt.Errorf("failed to find onvif profiles: %w", err)
	}

	if err := e.Next(); err != nil {
		return err
	}

	streams, err := e.App.FindCollectionByNameOrId("streams")
	if err != nil {
		return fmt.Errorf("failed to find streams collection: %w", err)
	}
	errGroup := &errgroup.Group{}
	for _, p := range onvifProfiles {
		log.Debug("Found ONVIF profile", "name", p.Name, "token", p.Token)
		errGroup.Go(func() error {
			log := log.With("profile", p.Token)
			rawURL := p.URI.String()
			rtspUrl := p.URI
			rtspUrl.User = url.UserPassword(camera.Username(), password)
			stats, err := ingest.GetStreamStats(e.Context, log, rtspUrl, string(p.Token))
			if err != nil {
				return fmt.Errorf("failed to get stream stats for profile %s: %w", p.Token, err)
			}
			log.Debug("Retrieved stream stats", "fps", stats.FPS, "width", stats.Width, "height", stats.Height)

			stream := &models.Stream{}
			stream.SetProxyRecord(core.NewRecord(streams))
			stream.SetCameraID(camera.Id)
			stream.SetURL(rawURL)
			stream.SetFPS(stats.FPS)
			stream.SetWidth(stats.Width)
			stream.SetHeight(stats.Height)
			return e.App.Save(stream)
		})
	}
	return errGroup.Wait()
}
