package repository

import (
	"bssapp-backend/models"
	"database/sql"
	"errors"
	"fmt"
	"log"
	"strings"
)

// UserRepository → kullanıcı işlemleri için repository katmanı
type UserRepository struct {
	DB *sql.DB
}

// NewUserRepository → yeni bir UserRepository döner
func NewUserRepository(db *sql.DB) *UserRepository {
	return &UserRepository{DB: db}
}

// -------------------------------------------------------
// 📋 GetUserList (User Management)
// -------------------------------------------------------
func (r *UserRepository) GetUserList() ([]models.User, error) {

	query := `
		SELECT
			u.id,
			u.code,
			COALESCE(u.upass,'') as upass,
			u.is_active,
			COALESCE(u.email,''),
			COALESCE(uru.dfrole_id, 0) AS role_id,
			COALESCE(dr.code, '')      AS role_code
		FROM dfusr u
		LEFT JOIN dfrole_usr uru ON u.id = uru.dfusr_id
		LEFT JOIN dfrole dr      ON dr.id = uru.dfrole_id
		ORDER BY u.code
	`

	rows, err := r.DB.Query(query)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var users []models.User
	for rows.Next() {
		var u models.User
		if err := rows.Scan(
			&u.ID,
			&u.Username,
			&u.Upass, // ✅ dfusr.upass
			&u.IsActive,
			&u.Email,
			&u.RoleID,
			&u.RoleCode,
		); err != nil {
			return nil, err
		}
		users = append(users, u)
	}
	return users, nil
}

// -------------------------------------------------------
// ➕ CreateUser (legacy dfusr insert)  [kullanıyorsan kalsın]
// -------------------------------------------------------
func (r *UserRepository) CreateUser(u *models.User) (int, error) {

	query := `
		INSERT INTO dfusr (
			code,
			upass,
			is_active,
			email,
			v3_username,
			v3usergroup
		)
		VALUES ($1, $2, $3, $4, $5, $6)
		RETURNING id
	`

	var newID int
	err := r.DB.QueryRow(
		query,
		u.Username,
		u.Upass, // ✅ upass
		u.IsActive,
		u.Email,
		u.V3Username,
		u.V3UserGroup,
	).Scan(&newID)

	if err != nil {
		return 0, err
	}
	return newID, nil
}

// -------------------------------------------------------
// 🔍 GetUserByUsername (legacy)  [login için şart değil ama düzelttim]
// -------------------------------------------------------
func (r *UserRepository) GetUserByUsername(username string) (*models.User, error) {

	clean := strings.TrimSpace(username)

	query := `
		SELECT
			u.id,
			u.code,
			COALESCE(u.upass,'') as upass,
			u.is_active,
			COALESCE(u.email,''),

			COALESCE(uru.dfrole_id,0) AS role_id,
			COALESCE(dr.code,'')     AS role_code,

			COALESCE(u.v3_username,'')  as v3_username,
			COALESCE(u.v3_usergroup,0)  as v3_usergroup,
			COALESCE(u.force_password_change,false) as force_password_change

		FROM dfusr u

		LEFT JOIN dfrole_usr uru
		  ON uru.dfusr_id = u.id

		LEFT JOIN dfrole dr
		  ON dr.id = uru.dfrole_id

		WHERE u.is_active = true
		  AND (
			LOWER(u.code)  = LOWER($1)
			OR LOWER(u.email) = LOWER($1)
		  )

		LIMIT 1;
	`

	row := r.DB.QueryRow(query, clean)

	var user models.User

	err := row.Scan(
		&user.ID,
		&user.Username,
		&user.Upass,
		&user.IsActive,
		&user.Email,

		&user.RoleID,
		&user.RoleCode,

		&user.V3Username,
		&user.V3UserGroup,
		&user.ForcePasswordChange,
	)

	if err != nil {

		if errors.Is(err, sql.ErrNoRows) {
			return nil, errors.New("kullanıcı bulunamadı")
		}

		return nil, err
	}

	return &user, nil
}

// -------------------------------------------------------
// 🧪 DebugListUsers
// -------------------------------------------------------
func (r *UserRepository) DebugListUsers() {
	rows, err := r.DB.Query(`SELECT id, code FROM dfusr ORDER BY id LIMIT 10`)
	if err != nil {
		fmt.Println("❌ [DEBUG] Listeleme hatası:", err)
		return
	}
	defer rows.Close()

	fmt.Println("📋 [DEBUG] İlk 10 kullanıcı:")
	for rows.Next() {
		var id int
		var code string
		if err := rows.Scan(&id, &code); err == nil {
			fmt.Printf(" - %d : %s\n", id, code)
		}
	}
}

// -------------------------------------------------------
// 🔁 SetUserRoles
// -------------------------------------------------------
func (r *UserRepository) SetUserRoles(userID int, roleIDs []int) error {

	tx, err := r.DB.Begin()
	if err != nil {
		return err
	}
	defer tx.Rollback()

	if _, err := tx.Exec(`DELETE FROM dfrole_usr WHERE dfusr_id = $1`, userID); err != nil {
		return err
	}

	for _, roleID := range roleIDs {
		if _, err := tx.Exec(
			`INSERT INTO dfrole_usr (dfrole_id, dfusr_id) VALUES ($1, $2)`,
			roleID, userID,
		); err != nil {
			return err
		}
	}

	return tx.Commit()
}

// -------------------------------------------------------
// 🔐 GetLegacyUserForLogin  ✅ LOGIN İÇİN TEK DOĞRU FONKSİYON
// -------------------------------------------------------
func (r *UserRepository) GetLegacyUserForLogin(login string) (*models.User, error) {
	log.Println("🟡 LEGACY LOGIN QUERY HIT:", login)

	login = strings.TrimSpace(login)

	var u models.User

	err := r.DB.QueryRow(`
		SELECT
			u.id,
			u.code,
			COALESCE(u.upass,'') as upass,
			u.is_active,
			COALESCE(u.email,''),
			COALESCE(ru.dfrole_id,0) as role_id,
			COALESCE(dr.code,'')    as role_code,
			COALESCE(u.force_password_change,false)
		FROM dfusr u
		LEFT JOIN LATERAL (
			SELECT dfrole_id
			FROM dfrole_usr
			WHERE dfusr_id = u.id
			ORDER BY dfrole_id
			LIMIT 1
		) ru ON true
		LEFT JOIN dfrole dr ON dr.id = ru.dfrole_id
		WHERE u.is_active = true
		  AND (
			LOWER(u.code)  = LOWER($1)
			OR LOWER(u.email) = LOWER($1)
		  )
		LIMIT 1
	`, login).Scan(
		&u.ID,
		&u.Username,
		&u.Upass,
		&u.IsActive,
		&u.Email,
		&u.RoleID,
		&u.RoleCode,
		&u.ForcePasswordChange,
	)

	if err != nil {
		log.Printf("❌ LEGACY SCAN ERROR: %v", err)
		return nil, err
	}

	prefix := u.Upass
	if len(prefix) > 4 {
		prefix = prefix[:4]
	}

	log.Printf(
		"🧪 LEGACY UPASS OK len=%d prefix=%s",
		len(u.Upass),
		prefix,
	)

	return &u, nil
}
