package repository

import (
	"time"

	"nex/backend/internal/config"
	"nex/backend/internal/domain"

	"gorm.io/gorm"

	appErrors "nex/backend/pkg/errors"
)

type providerRepository struct {
	db *gorm.DB
}

func NewProviderRepository(db *gorm.DB) ProviderRepository {
	return &providerRepository{db: db}
}

func (r *providerRepository) Create(provider *domain.Provider) error {
	p := toConfigProvider(provider)
	p.CreatedAt = time.Now()
	p.UpdatedAt = time.Now()
	return r.db.Create(&p).Error
}

func (r *providerRepository) GetByID(id string) (*domain.Provider, error) {
	var p config.Provider
	err := r.db.First(&p, "id = ?", id).Error
	if err != nil {
		return nil, err
	}
	d := toDomainProvider(&p)
	return &d, nil
}

func (r *providerRepository) List() ([]domain.Provider, error) {
	var providers []config.Provider
	err := r.db.Find(&providers).Error
	if err != nil {
		return nil, err
	}
	result := make([]domain.Provider, len(providers))
	for i := range providers {
		result[i] = toDomainProvider(&providers[i])
	}
	return result, nil
}

func (r *providerRepository) Update(id string, updates map[string]interface{}) error {
	updates["updated_at"] = time.Now()
	result := r.db.Model(&config.Provider{}).Where("id = ?", id).Updates(updates)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return appErrors.ErrProviderNotFound
	}
	return nil
}

func (r *providerRepository) Delete(id string) error {
	result := r.db.Delete(&config.Provider{}, "id = ?", id)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return appErrors.ErrProviderNotFound
	}
	return nil
}

func toDomainProvider(p *config.Provider) domain.Provider {
	return domain.Provider{
		ID:        p.ID,
		Name:      p.Name,
		APIKey:    p.APIKey,
		BaseURL:   p.BaseURL,
		Protocol:  p.Protocol,
		Enabled:   p.Enabled,
		CreatedAt: p.CreatedAt,
		UpdatedAt: p.UpdatedAt,
	}
}

func toConfigProvider(p *domain.Provider) config.Provider {
	return config.Provider{
		ID:       p.ID,
		Name:     p.Name,
		APIKey:   p.APIKey,
		BaseURL:  p.BaseURL,
		Protocol: p.Protocol,
		Enabled:  p.Enabled,
	}
}
