package repository

import (
	"context"

	"github.com/google/uuid"

	"apskel-pos-be/internal/entities"

	"gorm.io/gorm"
)

type ChartOfAccountTypeRepository interface {
	Create(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error
	GetByID(ctx context.Context, id uuid.UUID) (*entities.ChartOfAccountType, error)
	GetByCode(ctx context.Context, code string) (*entities.ChartOfAccountType, error)
	Update(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error
	Delete(ctx context.Context, id uuid.UUID) error
	List(ctx context.Context, filters map[string]interface{}, page, limit int) ([]*entities.ChartOfAccountType, int, error)
	GetActive(ctx context.Context) ([]*entities.ChartOfAccountType, error)
}

type ChartOfAccountTypeRepositoryImpl struct {
	db *gorm.DB
}

func NewChartOfAccountTypeRepositoryImpl(db *gorm.DB) *ChartOfAccountTypeRepositoryImpl {
	return &ChartOfAccountTypeRepositoryImpl{
		db: db,
	}
}

func (r *ChartOfAccountTypeRepositoryImpl) Create(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error {
	return r.db.WithContext(ctx).Create(chartOfAccountType).Error
}

func (r *ChartOfAccountTypeRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.ChartOfAccountType, error) {
	var chartOfAccountType entities.ChartOfAccountType
	err := r.db.WithContext(ctx).First(&chartOfAccountType, "id = ?", id).Error
	if err != nil {
		return nil, err
	}
	return &chartOfAccountType, nil
}

func (r *ChartOfAccountTypeRepositoryImpl) GetByCode(ctx context.Context, code string) (*entities.ChartOfAccountType, error) {
	var chartOfAccountType entities.ChartOfAccountType
	err := r.db.WithContext(ctx).First(&chartOfAccountType, "code = ?", code).Error
	if err != nil {
		return nil, err
	}
	return &chartOfAccountType, nil
}

func (r *ChartOfAccountTypeRepositoryImpl) Update(ctx context.Context, chartOfAccountType *entities.ChartOfAccountType) error {
	return r.db.WithContext(ctx).Save(chartOfAccountType).Error
}

func (r *ChartOfAccountTypeRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
	return r.db.WithContext(ctx).Delete(&entities.ChartOfAccountType{}, "id = ?", id).Error
}

func (r *ChartOfAccountTypeRepositoryImpl) List(ctx context.Context, filters map[string]interface{}, page, limit int) ([]*entities.ChartOfAccountType, int, error) {
	var chartOfAccountTypes []*entities.ChartOfAccountType
	var total int64

	query := r.db.WithContext(ctx).Model(&entities.ChartOfAccountType{})

	// Apply filters
	for key, value := range filters {
		if value != nil {
			query = query.Where(key+" = ?", value)
		}
	}

	// Count total
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// Apply pagination
	offset := (page - 1) * limit
	err := query.Offset(offset).Limit(limit).Find(&chartOfAccountTypes).Error
	return chartOfAccountTypes, int(total), err
}

func (r *ChartOfAccountTypeRepositoryImpl) GetActive(ctx context.Context) ([]*entities.ChartOfAccountType, error) {
	var chartOfAccountTypes []*entities.ChartOfAccountType
	err := r.db.WithContext(ctx).Where("is_active = ?", true).Find(&chartOfAccountTypes).Error
	return chartOfAccountTypes, err
}
