package repository

import (
	"database/sql"
	"time"

	"aggios-app/backend/internal/domain"

	"github.com/google/uuid"
)

// CompanyRepository handles database operations for companies
type CompanyRepository struct {
	db *sql.DB
}

// NewCompanyRepository creates a new company repository
func NewCompanyRepository(db *sql.DB) *CompanyRepository {
	return &CompanyRepository{db: db}
}

// Create creates a new company
func (r *CompanyRepository) Create(company *domain.Company) error {
	query := `
		INSERT INTO companies (id, cnpj, razao_social, nome_fantasia, email, telefone, status, tenant_id, created_by_user_id, created_at, updated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
		RETURNING id, created_at, updated_at
	`
	
	now := time.Now()
	company.ID = uuid.New()
	company.CreatedAt = now
	company.UpdatedAt = now
	
	return r.db.QueryRow(
		query,
		company.ID,
		company.CNPJ,
		company.RazaoSocial,
		company.NomeFantasia,
		company.Email,
		company.Telefone,
		company.Status,
		company.TenantID,
		company.CreatedByUserID,
		company.CreatedAt,
		company.UpdatedAt,
	).Scan(&company.ID, &company.CreatedAt, &company.UpdatedAt)
}

// FindByID finds a company by ID
func (r *CompanyRepository) FindByID(id uuid.UUID) (*domain.Company, error) {
	query := `
		SELECT id, cnpj, razao_social, nome_fantasia, email, telefone, status, tenant_id, created_by_user_id, created_at, updated_at
		FROM companies
		WHERE id = $1
	`
	
	company := &domain.Company{}
	err := r.db.QueryRow(query, id).Scan(
		&company.ID,
		&company.CNPJ,
		&company.RazaoSocial,
		&company.NomeFantasia,
		&company.Email,
		&company.Telefone,
		&company.Status,
		&company.TenantID,
		&company.CreatedByUserID,
		&company.CreatedAt,
		&company.UpdatedAt,
	)
	
	if err == sql.ErrNoRows {
		return nil, nil
	}
	
	return company, err
}

// FindByTenantID finds all companies for a tenant
func (r *CompanyRepository) FindByTenantID(tenantID uuid.UUID) ([]*domain.Company, error) {
	query := `
		SELECT id, cnpj, razao_social, nome_fantasia, email, telefone, status, tenant_id, created_by_user_id, created_at, updated_at
		FROM companies
		WHERE tenant_id = $1
		ORDER BY created_at DESC
	`
	
	rows, err := r.db.Query(query, tenantID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	
	var companies []*domain.Company
	for rows.Next() {
		company := &domain.Company{}
		err := rows.Scan(
			&company.ID,
			&company.CNPJ,
			&company.RazaoSocial,
			&company.NomeFantasia,
			&company.Email,
			&company.Telefone,
			&company.Status,
			&company.TenantID,
			&company.CreatedByUserID,
			&company.CreatedAt,
			&company.UpdatedAt,
		)
		if err != nil {
			return nil, err
		}
		companies = append(companies, company)
	}
	
	return companies, nil
}

// CNPJExists checks if a CNPJ is already registered for a tenant
func (r *CompanyRepository) CNPJExists(cnpj string, tenantID uuid.UUID) (bool, error) {
	var exists bool
	query := `SELECT EXISTS(SELECT 1 FROM companies WHERE cnpj = $1 AND tenant_id = $2)`
	err := r.db.QueryRow(query, cnpj, tenantID).Scan(&exists)
	return exists, err
}
