package repository

import (
	"strings"

	"git.mchus.pro/mchus/quoteforge/internal/models"
	"gorm.io/gorm"
)

type ConfigurationRepository struct {
	db *gorm.DB
}

func NewConfigurationRepository(db *gorm.DB) *ConfigurationRepository {
	return &ConfigurationRepository{db: db}
}

func (r *ConfigurationRepository) Create(config *models.Configuration) error {
	if err := r.db.Create(config).Error; err != nil {
		if isUnknownLineNoColumnError(err) {
			return r.db.Omit("line_no").Create(config).Error
		}
		return err
	}
	return nil
}

func (r *ConfigurationRepository) GetByID(id uint) (*models.Configuration, error) {
	var config models.Configuration
	err := r.db.First(&config, id).Error
	if err != nil {
		return nil, err
	}
	return &config, nil
}

func (r *ConfigurationRepository) GetByUUID(uuid string) (*models.Configuration, error) {
	var config models.Configuration
	err := r.db.Where("uuid = ?", uuid).First(&config).Error
	if err != nil {
		return nil, err
	}
	return &config, nil
}

func (r *ConfigurationRepository) Update(config *models.Configuration) error {
	if err := r.db.Save(config).Error; err != nil {
		if isUnknownLineNoColumnError(err) {
			return r.db.Omit("line_no").Save(config).Error
		}
		return err
	}
	return nil
}

func isUnknownLineNoColumnError(err error) bool {
	if err == nil {
		return false
	}
	msg := strings.ToLower(err.Error())
	return strings.Contains(msg, "unknown column 'line_no'") || strings.Contains(msg, "no column named line_no")
}

func (r *ConfigurationRepository) Delete(id uint) error {
	return r.db.Delete(&models.Configuration{}, id).Error
}

func (r *ConfigurationRepository) ListByUser(ownerUsername string, offset, limit int) ([]models.Configuration, int64, error) {
	var configs []models.Configuration
	var total int64

	ownerScope := "owner_username = ?"

	r.db.Model(&models.Configuration{}).Where(ownerScope, ownerUsername).Count(&total)
	err := r.db.
		Where(ownerScope, ownerUsername).
		Order("created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&configs).Error

	return configs, total, err
}

func (r *ConfigurationRepository) ListTemplates(offset, limit int) ([]models.Configuration, int64, error) {
	var configs []models.Configuration
	var total int64

	r.db.Model(&models.Configuration{}).Where("is_template = ?", true).Count(&total)
	err := r.db.
		Where("is_template = ?", true).
		Order("created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&configs).Error

	return configs, total, err
}

// ListAll returns all configurations without user filter
func (r *ConfigurationRepository) ListAll(offset, limit int) ([]models.Configuration, int64, error) {
	var configs []models.Configuration
	var total int64

	r.db.Model(&models.Configuration{}).Count(&total)
	err := r.db.
		Order("created_at DESC").
		Offset(offset).
		Limit(limit).
		Find(&configs).Error

	return configs, total, err
}
