package repository

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"

	"aggios-app/backend/internal/domain"

	"github.com/google/uuid"
)

type SignupTemplateRepository struct {
	db *sql.DB
}

func NewSignupTemplateRepository(db *sql.DB) *SignupTemplateRepository {
	return &SignupTemplateRepository{db: db}
}

// Create cria um novo template de cadastro
func (r *SignupTemplateRepository) Create(ctx context.Context, template *domain.SignupTemplate) error {
	formFieldsJSON, err := json.Marshal(template.FormFields)
	if err != nil {
		return fmt.Errorf("error marshaling form_fields: %w", err)
	}

	modulesJSON, err := json.Marshal(template.EnabledModules)
	if err != nil {
		return fmt.Errorf("error marshaling enabled_modules: %w", err)
	}

	query := `
		INSERT INTO signup_templates (
			name, description, slug, form_fields, enabled_modules,
			redirect_url, success_message, custom_logo_url, custom_primary_color,
			is_active, created_by
		) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
		RETURNING id, created_at, updated_at
	`

	err = r.db.QueryRowContext(
		ctx, query,
		template.Name, template.Description, template.Slug,
		formFieldsJSON, modulesJSON,
		template.RedirectURL, template.SuccessMessage,
		template.CustomLogoURL, template.CustomPrimaryColor,
		template.IsActive, template.CreatedBy,
	).Scan(&template.ID, &template.CreatedAt, &template.UpdatedAt)

	if err != nil {
		return fmt.Errorf("error creating signup template: %w", err)
	}

	return nil
}

// FindBySlug busca um template pelo slug
func (r *SignupTemplateRepository) FindBySlug(ctx context.Context, slug string) (*domain.SignupTemplate, error) {
	query := `
		SELECT id, name, description, slug, form_fields, enabled_modules,
		       redirect_url, success_message, custom_logo_url, custom_primary_color,
		       is_active, usage_count, created_by, created_at, updated_at
		FROM signup_templates
		WHERE slug = $1 AND is_active = true
	`

	var template domain.SignupTemplate
	var formFieldsJSON, modulesJSON []byte
	var redirectURL, successMessage, customLogoURL, customPrimaryColor sql.NullString

	err := r.db.QueryRowContext(ctx, query, slug).Scan(
		&template.ID, &template.Name, &template.Description, &template.Slug,
		&formFieldsJSON, &modulesJSON,
		&redirectURL, &successMessage,
		&customLogoURL, &customPrimaryColor,
		&template.IsActive, &template.UsageCount, &template.CreatedBy,
		&template.CreatedAt, &template.UpdatedAt,
	)

	if redirectURL.Valid {
		template.RedirectURL = redirectURL.String
	}
	if successMessage.Valid {
		template.SuccessMessage = successMessage.String
	}
	if customLogoURL.Valid {
		template.CustomLogoURL = customLogoURL.String
	}
	if customPrimaryColor.Valid {
		template.CustomPrimaryColor = customPrimaryColor.String
	}

	if err == sql.ErrNoRows {
		return nil, fmt.Errorf("signup template not found")
	}
	if err != nil {
		return nil, fmt.Errorf("error finding signup template: %w", err)
	}

	if err := json.Unmarshal(formFieldsJSON, &template.FormFields); err != nil {
		return nil, fmt.Errorf("error unmarshaling form_fields: %w", err)
	}

	if err := json.Unmarshal(modulesJSON, &template.EnabledModules); err != nil {
		return nil, fmt.Errorf("error unmarshaling enabled_modules: %w", err)
	}

	return &template, nil
}

// FindByID busca um template pelo ID
func (r *SignupTemplateRepository) FindByID(ctx context.Context, id uuid.UUID) (*domain.SignupTemplate, error) {
	query := `
		SELECT id, name, description, slug, form_fields, enabled_modules,
		       redirect_url, success_message, custom_logo_url, custom_primary_color,
		       is_active, usage_count, created_by, created_at, updated_at
		FROM signup_templates
		WHERE id = $1
	`

	var template domain.SignupTemplate
	var formFieldsJSON, modulesJSON []byte
	var redirectURL, successMessage, customLogoURL, customPrimaryColor sql.NullString

	err := r.db.QueryRowContext(ctx, query, id).Scan(
		&template.ID, &template.Name, &template.Description, &template.Slug,
		&formFieldsJSON, &modulesJSON,
		&redirectURL, &successMessage,
		&customLogoURL, &customPrimaryColor,
		&template.IsActive, &template.UsageCount, &template.CreatedBy,
		&template.CreatedAt, &template.UpdatedAt,
	)

	if redirectURL.Valid {
		template.RedirectURL = redirectURL.String
	}
	if successMessage.Valid {
		template.SuccessMessage = successMessage.String
	}
	if customLogoURL.Valid {
		template.CustomLogoURL = customLogoURL.String
	}
	if customPrimaryColor.Valid {
		template.CustomPrimaryColor = customPrimaryColor.String
	}

	if err == sql.ErrNoRows {
		return nil, fmt.Errorf("signup template not found")
	}
	if err != nil {
		return nil, fmt.Errorf("error finding signup template: %w", err)
	}

	if err := json.Unmarshal(formFieldsJSON, &template.FormFields); err != nil {
		return nil, fmt.Errorf("error unmarshaling form_fields: %w", err)
	}

	if err := json.Unmarshal(modulesJSON, &template.EnabledModules); err != nil {
		return nil, fmt.Errorf("error unmarshaling enabled_modules: %w", err)
	}

	return &template, nil
}

// List lista todos os templates
func (r *SignupTemplateRepository) List(ctx context.Context) ([]*domain.SignupTemplate, error) {
	query := `
		SELECT id, name, description, slug, form_fields, enabled_modules,
		       redirect_url, success_message, custom_logo_url, custom_primary_color,
		       is_active, usage_count, created_by, created_at, updated_at
		FROM signup_templates
		ORDER BY created_at DESC
	`

	rows, err := r.db.QueryContext(ctx, query)
	if err != nil {
		return nil, fmt.Errorf("error listing signup templates: %w", err)
	}
	defer rows.Close()

	var templates []*domain.SignupTemplate

	for rows.Next() {
		var template domain.SignupTemplate
		var formFieldsJSON, modulesJSON []byte
		var redirectURL, successMessage, customLogoURL, customPrimaryColor sql.NullString

		err := rows.Scan(
			&template.ID, &template.Name, &template.Description, &template.Slug,
			&formFieldsJSON, &modulesJSON,
			&redirectURL, &successMessage,
			&customLogoURL, &customPrimaryColor,
			&template.IsActive, &template.UsageCount, &template.CreatedBy,
			&template.CreatedAt, &template.UpdatedAt,
		)
		if err != nil {
			return nil, fmt.Errorf("error scanning signup template: %w", err)
		}

		if redirectURL.Valid {
			template.RedirectURL = redirectURL.String
		}
		if successMessage.Valid {
			template.SuccessMessage = successMessage.String
		}
		if customLogoURL.Valid {
			template.CustomLogoURL = customLogoURL.String
		}
		if customPrimaryColor.Valid {
			template.CustomPrimaryColor = customPrimaryColor.String
		}

		if err := json.Unmarshal(formFieldsJSON, &template.FormFields); err != nil {
			return nil, fmt.Errorf("error unmarshaling form_fields: %w", err)
		}

		if err := json.Unmarshal(modulesJSON, &template.EnabledModules); err != nil {
			return nil, fmt.Errorf("error unmarshaling enabled_modules: %w", err)
		}

		templates = append(templates, &template)
	}

	return templates, nil
}

// IncrementUsageCount incrementa o contador de uso
func (r *SignupTemplateRepository) IncrementUsageCount(ctx context.Context, id uuid.UUID) error {
	query := `UPDATE signup_templates SET usage_count = usage_count + 1 WHERE id = $1`
	_, err := r.db.ExecContext(ctx, query, id)
	return err
}

// Update atualiza um template
func (r *SignupTemplateRepository) Update(ctx context.Context, template *domain.SignupTemplate) error {
	formFieldsJSON, err := json.Marshal(template.FormFields)
	if err != nil {
		return fmt.Errorf("error marshaling form_fields: %w", err)
	}

	modulesJSON, err := json.Marshal(template.EnabledModules)
	if err != nil {
		return fmt.Errorf("error marshaling enabled_modules: %w", err)
	}

	query := `
		UPDATE signup_templates SET
			name = $1, description = $2, slug = $3, form_fields = $4, enabled_modules = $5,
			redirect_url = $6, success_message = $7, custom_logo_url = $8, custom_primary_color = $9,
			is_active = $10
		WHERE id = $11
	`

	_, err = r.db.ExecContext(
		ctx, query,
		template.Name, template.Description, template.Slug,
		formFieldsJSON, modulesJSON,
		template.RedirectURL, template.SuccessMessage,
		template.CustomLogoURL, template.CustomPrimaryColor,
		template.IsActive, template.ID,
	)

	if err != nil {
		return fmt.Errorf("error updating signup template: %w", err)
	}

	return nil
}

// Delete deleta um template
func (r *SignupTemplateRepository) Delete(ctx context.Context, id uuid.UUID) error {
	query := `DELETE FROM signup_templates WHERE id = $1`
	_, err := r.db.ExecContext(ctx, query, id)
	if err != nil {
		return fmt.Errorf("error deleting signup template: %w", err)
	}
	return nil
}
