package services

import (
	"context"
	"fmt"
	"time"

	"github.com/breakpilot/consent-service/internal/models"
	"github.com/google/uuid"
)

// SubmitForReview submits a version for review
func (s *EmailTemplateService) SubmitForReview(ctx context.Context, versionID, submitterID uuid.UUID, comment *string) error {
	tx, err := s.db.Begin(ctx)
	if err != nil {
		return fmt.Errorf("failed to begin transaction: %w", err)
	}
	defer tx.Rollback(ctx)

	// Update status
	_, err = tx.Exec(ctx, `
		UPDATE email_template_versions SET status = 'review', updated_at = $1 WHERE id = $2
	`, time.Now(), versionID)
	if err != nil {
		return fmt.Errorf("failed to update status: %w", err)
	}

	// Create approval record
	_, err = tx.Exec(ctx, `
		INSERT INTO email_template_approvals (id, version_id, approver_id, action, comment, created_at)
		VALUES ($1, $2, $3, $4, $5, $6)
	`, uuid.New(), versionID, submitterID, "submitted_for_review", comment, time.Now())
	if err != nil {
		return fmt.Errorf("failed to create approval record: %w", err)
	}

	return tx.Commit(ctx)
}

// ApproveVersion approves a version (DSB)
func (s *EmailTemplateService) ApproveVersion(ctx context.Context, versionID, approverID uuid.UUID, comment *string, scheduledPublishAt *time.Time) error {
	tx, err := s.db.Begin(ctx)
	if err != nil {
		return fmt.Errorf("failed to begin transaction: %w", err)
	}
	defer tx.Rollback(ctx)

	now := time.Now()
	status := "approved"
	if scheduledPublishAt != nil {
		status = "scheduled"
	}

	_, err = tx.Exec(ctx, `
		UPDATE email_template_versions
		SET status = $1, approved_by = $2, approved_at = $3, scheduled_publish_at = $4, updated_at = $5
		WHERE id = $6
	`, status, approverID, now, scheduledPublishAt, now, versionID)
	if err != nil {
		return fmt.Errorf("failed to approve version: %w", err)
	}

	_, err = tx.Exec(ctx, `
		INSERT INTO email_template_approvals (id, version_id, approver_id, action, comment, created_at)
		VALUES ($1, $2, $3, $4, $5, $6)
	`, uuid.New(), versionID, approverID, "approved", comment, now)
	if err != nil {
		return fmt.Errorf("failed to create approval record: %w", err)
	}

	return tx.Commit(ctx)
}

// PublishVersion publishes an approved version
func (s *EmailTemplateService) PublishVersion(ctx context.Context, versionID, publisherID uuid.UUID) error {
	tx, err := s.db.Begin(ctx)
	if err != nil {
		return fmt.Errorf("failed to begin transaction: %w", err)
	}
	defer tx.Rollback(ctx)

	// Get version info to find template and language
	var templateID uuid.UUID
	var language string
	err = tx.QueryRow(ctx, `SELECT template_id, language FROM email_template_versions WHERE id = $1`, versionID).Scan(&templateID, &language)
	if err != nil {
		return fmt.Errorf("failed to get version info: %w", err)
	}

	// Archive old published versions for same template and language
	_, err = tx.Exec(ctx, `
		UPDATE email_template_versions
		SET status = 'archived', updated_at = $1
		WHERE template_id = $2 AND language = $3 AND status = 'published'
	`, time.Now(), templateID, language)
	if err != nil {
		return fmt.Errorf("failed to archive old versions: %w", err)
	}

	// Publish the new version
	now := time.Now()
	_, err = tx.Exec(ctx, `
		UPDATE email_template_versions
		SET status = 'published', published_at = $1, updated_at = $2
		WHERE id = $3
	`, now, now, versionID)
	if err != nil {
		return fmt.Errorf("failed to publish version: %w", err)
	}

	// Create approval record
	_, err = tx.Exec(ctx, `
		INSERT INTO email_template_approvals (id, version_id, approver_id, action, created_at)
		VALUES ($1, $2, $3, $4, $5)
	`, uuid.New(), versionID, publisherID, "published", now)
	if err != nil {
		return fmt.Errorf("failed to create approval record: %w", err)
	}

	return tx.Commit(ctx)
}

// RejectVersion rejects a version
func (s *EmailTemplateService) RejectVersion(ctx context.Context, versionID, rejectorID uuid.UUID, comment string) error {
	tx, err := s.db.Begin(ctx)
	if err != nil {
		return fmt.Errorf("failed to begin transaction: %w", err)
	}
	defer tx.Rollback(ctx)

	now := time.Now()
	_, err = tx.Exec(ctx, `
		UPDATE email_template_versions SET status = 'draft', updated_at = $1 WHERE id = $2
	`, now, versionID)
	if err != nil {
		return fmt.Errorf("failed to reject version: %w", err)
	}

	_, err = tx.Exec(ctx, `
		INSERT INTO email_template_approvals (id, version_id, approver_id, action, comment, created_at)
		VALUES ($1, $2, $3, $4, $5, $6)
	`, uuid.New(), versionID, rejectorID, "rejected", &comment, now)
	if err != nil {
		return fmt.Errorf("failed to create approval record: %w", err)
	}

	return tx.Commit(ctx)
}

// GetApprovals returns approval history for a version
func (s *EmailTemplateService) GetApprovals(ctx context.Context, versionID uuid.UUID) ([]models.EmailTemplateApproval, error) {
	rows, err := s.db.Query(ctx, `
		SELECT id, version_id, approver_id, action, comment, created_at
		FROM email_template_approvals
		WHERE version_id = $1
		ORDER BY created_at DESC
	`, versionID)
	if err != nil {
		return nil, fmt.Errorf("failed to get approvals: %w", err)
	}
	defer rows.Close()

	var approvals []models.EmailTemplateApproval
	for rows.Next() {
		var a models.EmailTemplateApproval
		err := rows.Scan(&a.ID, &a.VersionID, &a.ApproverID, &a.Action, &a.Comment, &a.CreatedAt)
		if err != nil {
			return nil, fmt.Errorf("failed to scan approval: %w", err)
		}
		approvals = append(approvals, a)
	}

	return approvals, nil
}
