package chat

import (
	"context"
	"log"
	"sync"
	"sync/atomic"

	"git.ali33.ru/fcg-xvii/rest"
)

func New() *Chat {
	res := &Chat{
		users:     &sync.Map{},
		idCounter: &atomic.Int64{},
		chConnect: make(chan rest.IStream, 5),
	}
	go res.work()
	return res
}

type Chat struct {
	ctx       context.Context
	cancel    context.CancelFunc
	users     *sync.Map
	idCounter *atomic.Int64
	chConnect chan rest.IStream
}

func (s *Chat) Close() {
	s.cancel()
}

func (s *Chat) work() {
	s.ctx, s.cancel = context.WithCancel(context.Background())
	for {
		select {
		case <-s.ctx.Done():
			return
		case stream := <-s.chConnect:
			log.Println("CONNECT-------")
			go func() {
				<-stream.Context().Done()
				log.Println("DISCONNECT-------")
			}()
		}
	}
}

func (s *Chat) Connect() chan<- rest.IStream {
	return s.chConnect
}

func (s *Chat) Register(name, password string) *User {
	user := &User{
		ID:       s.idCounter.Add(1),
		Name:     name,
		Password: password,
	}
	s.users.Store(user.ID, user)
	return user
}

func (s *Chat) SearchByID(id int64) (*User, bool) {
	if u, check := s.users.Load(id); check {
		return u.(*User), true
	}
	return nil, false
}

func (s *Chat) Auth(name, password string) (res *User, check bool) {
	s.users.Range(func(key, val any) bool {
		u := val.(*User)
		if u.Name == name && u.Password == password {
			res, check = u, true
			return false
		}
		return true
	})
	return
}