package economy

import "context"

// Carpet یک فرشِ ایرانی که به‌جای میزِ بازی استفاده می‌شود. Owned یعنی قابلِ انتخاب.
type Carpet struct {
	ID         string `json:"id"`
	Title      string `json:"title"`
	PriceCoins int64  `json:"price_coins"`
	VIP        bool   `json:"vip"`
	Owned      bool   `json:"owned"`
}

// Carpets فرش‌های فعال را با وضعیتِ مالکیتِ کاربر برمی‌گرداند.
func (s *Service) Carpets(ctx context.Context, userID int64) ([]Carpet, error) {
	rows, err := s.db.QueryContext(ctx,
		`SELECT id, title, price_coins, vip FROM carpets WHERE enabled = 1 ORDER BY sort`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var carpets []Carpet
	for rows.Next() {
		var c Carpet
		var vip int
		if err := rows.Scan(&c.ID, &c.Title, &c.PriceCoins, &vip); err != nil {
			return nil, err
		}
		c.VIP = vip == 1
		carpets = append(carpets, c)
	}
	if err := rows.Err(); err != nil {
		return nil, err
	}

	owned, err := s.ownedCarpets(ctx, userID)
	if err != nil {
		return nil, err
	}
	isVIP := s.isVIP(ctx, userID)
	for i := range carpets {
		c := &carpets[i]
		c.Owned = (c.PriceCoins == 0 && !c.VIP) || (c.VIP && isVIP) || owned[c.ID]
	}
	return carpets, nil
}

func (s *Service) ownedCarpets(ctx context.Context, userID int64) (map[string]bool, error) {
	rows, err := s.db.QueryContext(ctx,
		`SELECT carpet_id FROM user_carpets WHERE user_id = ?`, userID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	owned := map[string]bool{}
	for rows.Next() {
		var id string
		if err := rows.Scan(&id); err != nil {
			return nil, err
		}
		owned[id] = true
	}
	return owned, rows.Err()
}

// BuyCarpet یک فرش را با سکه باز می‌کند.
func (s *Service) BuyCarpet(ctx context.Context, userID int64, carpetID string) error {
	var price int64
	var vip, enabled int
	err := s.db.QueryRowContext(ctx,
		`SELECT price_coins, vip, enabled FROM carpets WHERE id = ?`, carpetID).
		Scan(&price, &vip, &enabled)
	if err != nil || enabled != 1 {
		return ErrNotFound
	}
	tx, err := s.db.BeginTx(ctx, nil)
	if err != nil {
		return err
	}
	defer tx.Rollback()

	var exists int
	_ = tx.QueryRowContext(ctx,
		`SELECT 1 FROM user_carpets WHERE user_id = ? AND carpet_id = ?`, userID, carpetID).Scan(&exists)
	if exists == 1 {
		return ErrAlreadyOwned
	}
	if price > 0 {
		if err := adjustTx(ctx, tx, userID, CurrencyCoin, -price, "buy_carpet", carpetID); err != nil {
			return err
		}
	}
	if _, err := tx.ExecContext(ctx,
		`INSERT INTO user_carpets (user_id, carpet_id) VALUES (?, ?)`, userID, carpetID); err != nil {
		return err
	}
	return tx.Commit()
}

// SelectCarpet فرشِ انتخابیِ کاربر را تنظیم می‌کند (باید مالکش باشد یا رایگان/VIP).
func (s *Service) SelectCarpet(ctx context.Context, userID int64, carpetID string) error {
	carpets, err := s.Carpets(ctx, userID)
	if err != nil {
		return err
	}
	for _, c := range carpets {
		if c.ID == carpetID {
			if !c.Owned {
				return ErrNotOwned
			}
			_, err := s.db.ExecContext(ctx,
				`UPDATE users SET selected_carpet = ? WHERE id = ?`, carpetID, userID)
			return err
		}
	}
	return ErrNotFound
}
