package repository

import (
	"context"
	"database/sql"
	"fmt"
	"time"

	dbgen "Yimaru-Backend/gen/db"
	"Yimaru-Backend/internal/domain"
	"Yimaru-Backend/internal/ports"

	"github.com/jackc/pgx/v5/pgtype"
)

// Interface for creating new otp store
func NewOTPStore(s *Store) ports.OtpStore { return s }

func (s *Store) UpdateOtp(ctx context.Context, otp string, userId int64) error {
	return s.queries.UpdateExpiredOtp(ctx, dbgen.UpdateExpiredOtpParams{
		UserID: userId,
		Otp:    otp,
		ExpiresAt: pgtype.Timestamptz{
			Time:  time.Now().Add(5 * time.Minute),
			Valid: true,
		},
	})
}

func (s *Store) CreateOtp(ctx context.Context, otp domain.Otp) error {
	return s.queries.CreateOtp(ctx, dbgen.CreateOtpParams{
		UserID: otp.UserID,
		SentTo: otp.SentTo,
		Medium: string(otp.Medium),
		OtpFor: string(otp.For),
		Otp:    otp.Otp,
		ExpiresAt: pgtype.Timestamptz{
			Time:  otp.ExpiresAt,
			Valid: true,
		},
	})
}

func (s *Store) GetOtp(ctx context.Context, userID int64) (domain.Otp, error) {
	row, err := s.queries.GetOtp(ctx, userID)
	if err != nil {
		fmt.Printf("OTP REPO error: %v userName: %v\n", err, userID)
		if err == sql.ErrNoRows {
			return domain.Otp{}, domain.ErrOtpNotFound
		}
		return domain.Otp{}, err
	}
	return domain.Otp{
		ID:        row.ID,
		UserID:    row.UserID,
		SentTo:    row.SentTo,
		Medium:    domain.OtpMedium(row.Medium),
		For:       domain.OtpFor(row.OtpFor),
		Otp:       row.Otp,
		Used:      row.Used,
		UsedAt:    row.UsedAt.Time,
		CreatedAt: row.CreatedAt.Time,
		ExpiresAt: row.ExpiresAt.Time,
	}, nil
}
func (s *Store) MarkOtpAsUsed(ctx context.Context, otp domain.Otp) error {
	return s.queries.MarkOtpAsUsed(ctx, dbgen.MarkOtpAsUsedParams{
		ID: otp.ID,
		UsedAt: pgtype.Timestamptz{
			Time:  otp.UsedAt,
			Valid: true,
		},
	})
}
