package main

import (
	"context"
	"log"
	"time"

	"github.com/gofrs/uuid/v5"
	_ "github.com/jackc/pgx/v5/stdlib"
	"github.com/jmoiron/sqlx"
	"golang.org/x/crypto/bcrypt"

	"github.com/saveinmed/backend-go/internal/config"
	"github.com/saveinmed/backend-go/internal/domain"
)

func main() {
	cfg, err := config.Load()
	if err != nil {
		log.Fatalf("failed to load config: %v", err)
	}

	db, err := sqlx.Open("pgx", cfg.DatabaseURL)
	if err != nil {
		log.Fatalf("Failed to connect to DB: %v", err)
	}
	defer db.Close()

	if err := db.Ping(); err != nil {
		log.Fatalf("Failed to ping DB: %v", err)
	}

	ctx := context.Background()

	log.Println("🌱 Restoring Admin and creating new Lojista...")

	// 1. Create/Update Admin
	adminUser := &domain.User{
		Role:          "Admin",
		Name:          "Administrador",
		Username:      "admin_master",
		Email:         "admin@saveinmed.com",
		EmailVerified: true,
	}
	createUserWithEmail(ctx, db, adminUser, "teste123", cfg.PasswordPepper)
	log.Println("✅ Admin account restored (admin@saveinmed.com / teste123)")

	// 2. Create Second Lojista (Company + User)
	companyID := uuid.Must(uuid.NewV7())
	company := &domain.Company{
		ID:            companyID,
		CNPJ:          "98765432000188",
		CorporateName: "Farma Central Distribuidora",
		Category:      "distribuidora",
		LicenseNumber: "LIC-987654",
		IsVerified:    true,
		Latitude:      -23.5611,
		Longitude:     -46.6559,
		City:          "São Paulo",
		State:         "SP",
	}
	actualCompanyID := createCompany(ctx, db, company)

	lojista2User := &domain.User{
		CompanyID:     actualCompanyID,
		Role:          "Dono",
		Name:          "Ricardo Lojista",
		Username:      "ricardo_farma",
		Email:         "ricardo@farmacentral.com",
		EmailVerified: true,
	}
	createUserWithEmail(ctx, db, lojista2User, "password123", cfg.PasswordPepper)
	log.Println("✅ Ricardo Lojista created (ricardo@farmacentral.com / password123)")

	// 3. Create Pharmacy (Buyer)
	pharmacyCompID := uuid.Must(uuid.NewV7())
	pharmacyCompany := &domain.Company{
		ID:            pharmacyCompID,
		CNPJ:          "12345678000199",
		CorporateName: "Farmácia de Teste",
		Category:      "farmacia",
		LicenseNumber: "LIC-123456",
		IsVerified:    true,
		City:          "São Paulo",
		State:         "SP",
	}
	actualPharmacyID := createCompany(ctx, db, pharmacyCompany)

	pharmacyUser := &domain.User{
		CompanyID:     actualPharmacyID,
		Role:          "Dono",
		Name:          "Dono da Farmácia",
		Username:      "farmacia_user_new",
		Email:         "farmacia@saveinmed.com",
		EmailVerified: true,
	}
	createUserWithEmail(ctx, db, pharmacyUser, "123456", cfg.PasswordPepper)
	log.Println("✅ Pharmacy Buyer created (farmacia@saveinmed.com / 123456)")

	log.Println("✅ Seeding complete!")
}

func createCompany(ctx context.Context, db *sqlx.DB, c *domain.Company) uuid.UUID {
	c.CreatedAt = time.Now().UTC()
	c.UpdatedAt = time.Now().UTC()

	var id uuid.UUID
	err := db.QueryRowContext(ctx, `
		INSERT INTO companies (id, cnpj, corporate_name, category, license_number, is_verified, latitude, longitude, city, state, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
		ON CONFLICT (cnpj) DO UPDATE SET
			corporate_name = EXCLUDED.corporate_name,
			updated_at = EXCLUDED.updated_at
		RETURNING id
	`, c.ID, c.CNPJ, c.CorporateName, c.Category, c.LicenseNumber, c.IsVerified, c.Latitude, c.Longitude, c.City, c.State, c.CreatedAt, c.UpdatedAt).Scan(&id)

	if err != nil {
		log.Printf("Error creating company %s: %v", c.CNPJ, err)
		// Fallback: try to get the ID if insert failed but company exists
		_ = db.GetContext(ctx, &id, "SELECT id FROM companies WHERE cnpj = $1", c.CNPJ)
	} else {
		log.Printf("Company %s created/updated successfully with ID %s", c.CNPJ, id)
	}
	return id
}

func createUserWithEmail(ctx context.Context, db *sqlx.DB, u *domain.User, password, pepper string) {
	hashed, _ := bcrypt.GenerateFromPassword([]byte(password+pepper), bcrypt.DefaultCost)
	u.ID = uuid.Must(uuid.NewV7())
	u.PasswordHash = string(hashed)
	u.CreatedAt = time.Now().UTC()
	u.UpdatedAt = time.Now().UTC()

	_, err := db.NamedExecContext(ctx, `
		INSERT INTO users (id, company_id, role, name, username, email, password_hash, email_verified, created_at, updated_at)
		VALUES (:id, :company_id, :role, :name, :username, :email, :password_hash, :email_verified, :created_at, :updated_at)
		ON CONFLICT (email) DO UPDATE SET
			password_hash = EXCLUDED.password_hash,
			company_id = COALESCE(EXCLUDED.company_id, users.company_id),
			role = EXCLUDED.role,
			username = EXCLUDED.username,
			updated_at = EXCLUDED.updated_at
	`, u)
	if err != nil {
		log.Printf("Error creating user %s: %v", u.Email, err)
	} else {
		log.Printf("User %s created/updated successfully", u.Email)
	}
}
