package storage

import (
	"context"
	"fmt"
	"sync"

	"git.espin.casa/albert/cml04-falcon-printer/types"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

type Storager interface {
	ListProductionOrders(ctx context.Context, limit int) ([]*types.ProductionOrder, error)
	ListCostumerOrders(ctx context.Context, po int) ([]*types.CustomerOrder, error)
}

type storage struct {
	db  *gorm.DB
	mux sync.RWMutex
}

// ListCostumerOrders implements Storager.
func (s *storage) ListCostumerOrders(ctx context.Context, po int) ([]*types.CustomerOrder, error) {
	cos := []*types.CustomerOrder{}
	if err := s.db.WithContext(ctx).Order("c_order_no desc").Where("p_order_no = ?,po").Error; err != nil {
		return nil, err
	}
	return cos, nil
}

// ListProductionOrders implements Storager.
func (s *storage) ListProductionOrders(ctx context.Context, limit int) ([]*types.ProductionOrder, error) {
	pos := []*types.ProductionOrder{}
	if err := s.db.WithContext(ctx).Order("created_at,p_order_no desc").Limit(limit).Find(&pos).Error; err != nil {
		return nil, err
	}
	return pos, nil
}

type DBConfig struct {
	Username string
	Password string
	Host     string
	Port     int
	Name     string
}

func ProductionDataBase(conf *DBConfig) (*gorm.DB, error) {
	// create dsn string
	dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=disable TimeZone=Europe/Madrid",
		conf.Host,
		conf.Username,
		conf.Password,
		conf.Name,
		conf.Port,
	)
	// create open database connection
	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
	if err != nil {
		return nil, err
	}
	return db, nil
}

func New(conf *DBConfig) (Storager, error) {
	// database holder
	var db *gorm.DB
	// producctio
	db, err := ProductionDataBase(conf)
	if err != nil {
		return nil, err
	}
	// done
	return &storage{
		db:  db,
		mux: sync.RWMutex{},
	}, nil
}
