package db

import (
	"context"
	"encoding/json"
)

func (r *PGRepository) ListAllTenants(ctx context.Context, limit, offset int) ([]TenantRecord, int, error) {
	var total int
	err := r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM tenants`).Scan(&total)
	if err != nil {
		return nil, 0, err
	}

	rows, err := r.pool.Query(ctx, `
		SELECT id, slug, name, preset, locale, timezone, plan_code, subscription_status,
		       COALESCE(billing_provider, 'stripe'), billing_customer_id, billing_subscription_id
		FROM tenants
		ORDER BY created_at DESC
		LIMIT $1 OFFSET $2
	`, limit, offset)
	if err != nil {
		return nil, 0, err
	}
	defer rows.Close()

	var tenants []TenantRecord
	for rows.Next() {
		var t TenantRecord
		if err := rows.Scan(
			&t.ID, &t.Slug, &t.Name, &t.Preset, &t.Locale, &t.Timezone,
			&t.PlanCode, &t.SubscriptionStatus, &t.BillingProvider,
			&t.BillingCustomerID, &t.BillingSubscription,
		); err != nil {
			return nil, 0, err
		}
		tenants = append(tenants, t)
	}

	return tenants, total, nil
}

func (r *PGRepository) ListAllUsers(ctx context.Context, limit, offset int) ([]UserRecord, int, error) {
	var total int
	err := r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM users`).Scan(&total)
	if err != nil {
		return nil, 0, err
	}

	rows, err := r.pool.Query(ctx, `
		SELECT id, email, name, email_verified, provider, role, created_at, last_login_at
		FROM users
		ORDER BY created_at DESC
		LIMIT $1 OFFSET $2
	`, limit, offset)
	if err != nil {
		return nil, 0, err
	}
	defer rows.Close()

	var users []UserRecord
	for rows.Next() {
		var u UserRecord
		if err := rows.Scan(
			&u.ID, &u.Email, &u.Name, &u.EmailVerified, &u.Provider, &u.Role,
			&u.CreatedAt, &u.LastLoginAt,
		); err != nil {
			return nil, 0, err
		}
		users = append(users, u)
	}

	return users, total, nil
}

func (r *PGRepository) GetPlatformStats(ctx context.Context) (PlatformStats, error) {
	var stats PlatformStats

	// Total tenants
	r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM tenants`).Scan(&stats.TotalTenants)

	// Total users
	r.pool.QueryRow(ctx, `SELECT COUNT(*) FROM users`).Scan(&stats.TotalUsers)

	// Active subscriptions
	r.pool.QueryRow(ctx, `
		SELECT COUNT(*) FROM billing_snapshots 
		WHERE status IN ('active', 'trialing')
	`).Scan(&stats.ActiveSubscriptions)

	// Trial subscriptions
	r.pool.QueryRow(ctx, `
		SELECT COUNT(*) FROM billing_snapshots 
		WHERE status = 'trialing'
	`).Scan(&stats.TrialSubscriptions)

	// Bookings this month
	r.pool.QueryRow(ctx, `
		SELECT COUNT(*) FROM bookings 
		WHERE created_at >= date_trunc('month', CURRENT_DATE)
	`).Scan(&stats.BookingsThisMonth)

	return stats, nil
}

func (r *PGRepository) CreateAdminAuditLog(ctx context.Context, params AdminAuditLogParams) error {
	var detailsJSON []byte
	var err error
	if params.Details != nil {
		detailsJSON, err = json.Marshal(params.Details)
		if err != nil {
			return err
		}
	}

	_, err = r.pool.Exec(ctx, `
		INSERT INTO admin_audit_log (admin_user_id, action, resource_type, resource_id, details, ip_address, user_agent)
		VALUES ($1, $2, $3, $4, $5, $6, $7)
	`, nullableUUID(params.AdminUserID), params.Action, params.ResourceType, params.ResourceID, detailsJSON, params.IPAddress, params.UserAgent)
	return err
}

func (r *PGRepository) UpdateUserRole(ctx context.Context, userID, role string) error {
	_, err := r.pool.Exec(ctx, `
		UPDATE users SET role = $1, updated_at = NOW() WHERE id = $2
	`, role, userID)
	return err
}

func nullableUUID(s string) interface{} {
	if s == "" {
		return nil
	}
	return s
}
