package postgres

import (
	"context"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/store"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
	"gorm.io/gorm"
)

type ShopSeriesAllocationStore struct {
	db *gorm.DB
}

func NewShopSeriesAllocationStore(db *gorm.DB) *ShopSeriesAllocationStore {
	return &ShopSeriesAllocationStore{db: db}
}

func (s *ShopSeriesAllocationStore) Create(ctx context.Context, allocation *model.ShopSeriesAllocation) error {
	return s.db.WithContext(ctx).Create(allocation).Error
}

func (s *ShopSeriesAllocationStore) GetByID(ctx context.Context, id uint) (*model.ShopSeriesAllocation, error) {
	var allocation model.ShopSeriesAllocation
	query := s.db.WithContext(ctx).Where("id = ?", id)
	// 应用数据权限过滤：代理只能访问自己分配出去的记录
	query = middleware.ApplyAllocatorShopFilter(ctx, query)
	if err := query.First(&allocation).Error; err != nil {
		return nil, err
	}
	return &allocation, nil
}

func (s *ShopSeriesAllocationStore) GetByShopAndSeries(ctx context.Context, shopID, seriesID uint) (*model.ShopSeriesAllocation, error) {
	var allocation model.ShopSeriesAllocation
	query := s.db.WithContext(ctx).
		Where("shop_id = ? AND series_id = ?", shopID, seriesID)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.First(&allocation).Error; err != nil {
		return nil, err
	}
	return &allocation, nil
}

func (s *ShopSeriesAllocationStore) Update(ctx context.Context, allocation *model.ShopSeriesAllocation) error {
	return s.db.WithContext(ctx).Save(allocation).Error
}

func (s *ShopSeriesAllocationStore) Delete(ctx context.Context, id uint) error {
	return s.db.WithContext(ctx).Delete(&model.ShopSeriesAllocation{}, id).Error
}

func (s *ShopSeriesAllocationStore) List(ctx context.Context, opts *store.QueryOptions, filters map[string]interface{}) ([]*model.ShopSeriesAllocation, int64, error) {
	var allocations []*model.ShopSeriesAllocation
	var total int64

	query := s.db.WithContext(ctx).Model(&model.ShopSeriesAllocation{})
	// 应用数据权限过滤：代理只能看到自己分配出去的记录
	query = middleware.ApplyAllocatorShopFilter(ctx, query)

	if shopID, ok := filters["shop_id"].(uint); ok && shopID > 0 {
		query = query.Where("shop_id = ?", shopID)
	}
	if seriesID, ok := filters["series_id"].(uint); ok && seriesID > 0 {
		query = query.Where("series_id = ?", seriesID)
	}
	if allocatorShopID, ok := filters["allocator_shop_id"].(uint); ok {
		query = query.Where("allocator_shop_id = ?", allocatorShopID)
	}
	if status, ok := filters["status"].(int); ok && status > 0 {
		query = query.Where("status = ?", status)
	}

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

	if opts == nil {
		opts = store.DefaultQueryOptions()
	}
	offset := (opts.Page - 1) * opts.PageSize
	query = query.Offset(offset).Limit(opts.PageSize)

	if opts.OrderBy != "" {
		query = query.Order(opts.OrderBy)
	} else {
		query = query.Order("id DESC")
	}

	if err := query.Find(&allocations).Error; err != nil {
		return nil, 0, err
	}

	return allocations, total, nil
}

func (s *ShopSeriesAllocationStore) UpdateStatus(ctx context.Context, id uint, status int, updater uint) error {
	return s.db.WithContext(ctx).
		Model(&model.ShopSeriesAllocation{}).
		Where("id = ?", id).
		Updates(map[string]interface{}{
			"status":  status,
			"updater": updater,
		}).Error
}

func (s *ShopSeriesAllocationStore) GetByShopID(ctx context.Context, shopID uint) ([]*model.ShopSeriesAllocation, error) {
	var allocations []*model.ShopSeriesAllocation
	query := s.db.WithContext(ctx).
		Where("shop_id = ? AND status = 1", shopID)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.Find(&allocations).Error; err != nil {
		return nil, err
	}
	return allocations, nil
}

func (s *ShopSeriesAllocationStore) CountBySeriesID(ctx context.Context, seriesID uint) (int64, error) {
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.ShopSeriesAllocation{}).
		Where("series_id = ?", seriesID).
		Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

func (s *ShopSeriesAllocationStore) ExistsByShopAndSeries(ctx context.Context, shopID, seriesID uint) (bool, error) {
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.ShopSeriesAllocation{}).
		Where("shop_id = ? AND series_id = ?", shopID, seriesID).
		Count(&count).Error; err != nil {
		return false, err
	}
	return count > 0, nil
}

func (s *ShopSeriesAllocationStore) GetByAllocatorShopID(ctx context.Context, allocatorShopID uint) ([]*model.ShopSeriesAllocation, error) {
	var allocations []*model.ShopSeriesAllocation
	query := s.db.WithContext(ctx).
		Where("allocator_shop_id = ? AND status = 1", allocatorShopID)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.Find(&allocations).Error; err != nil {
		return nil, err
	}
	return allocations, nil
}

func (s *ShopSeriesAllocationStore) GetIDsByShopIDsAndSeries(ctx context.Context, shopIDs []uint, seriesID uint) ([]uint, error) {
	if len(shopIDs) == 0 {
		return nil, nil
	}
	var ids []uint
	query := s.db.WithContext(ctx).
		Model(&model.ShopSeriesAllocation{}).
		Where("shop_id IN ? AND series_id = ? AND status = 1", shopIDs, seriesID)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.Pluck("id", &ids).Error; err != nil {
		return nil, err
	}
	return ids, nil
}
