package db

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"math/rand"

	"github.com/FernandoVideira/LK_API_Temp/internal/store"
)

var first_names = []string{
	"Alice", "Bob", "Charlie", "Dave", "Eve", "Frank", "Grace", "Heidi", "Ivan", "Judy",
	"Mallory", "Nathan", "Olivia", "Peggy", "Quinn", "Rachel", "Sam", "Trent", "Ursula", "Victor",
	"Wendy", "Xander", "Yvonne", "Zach", "Amy", "Brian", "Carl", "Diana", "Edward", "Fiona",
	"George", "Hannah", "Ian", "Jessica", "Kevin", "Lisa", "Michael", "Nina", "Oscar", "Paula",
	"Quentin", "Rebecca", "Steve", "Tina", "Uma", "Vincent", "Willow", "Xenia", "Yuri", "Zoe",
}

var last_names = []string{
	"Smith", "Johnson", "Williams", "Jones", "Brown", "Davis", "Miller", "Wilson", "Moore", "Taylor",
	"Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", "Thompson", "Garcia", "Martinez", "Robinson",
	"Clark", "Rodriguez", "Lewis", "Lee", "Walker", "Hall", "Allen", "Young", "Hernandez", "King",
	"Wright", "Lopez", "Hill", "Scott", "Green", "Adams", "Baker", "Gonzalez", "Nelson", "Carter",
	"Mitchell", "Perez", "Roberts", "Turner", "Phillips", "Campbell", "Parker", "Evans", "Edwards", "Collins",
}

var usernames = []string{
	"alice", "bob", "charlie", "dave", "eve", "frank", "grace", "heidi", "ivan", "judy",
	"mallory", "nathan", "olivia", "peggy", "quinn", "rachel", "sam", "trent", "ursula", "victor",
	"wendy", "xander", "yvonne", "zach", "amy", "brian", "carl", "diana", "edward", "fiona",
	"george", "hannah", "ian", "jessica", "kevin", "lisa", "michael", "nina", "oscar", "paula",
	"quentin", "rebecca", "steve", "tina", "uma", "vincent", "willow", "xenia", "yuri", "zoe",
}

var titles = []string{
	"How to Learn Go in 10 Days",
	"Understanding Concurrency in Go",
	"Building REST APIs with Go",
	"Mastering Go: Tips and Tricks",
	"Go vs. Python: A Comparison",
	"Error Handling in Go",
	"Go Routines and Channels Explained",
	"Building a Web Server in Go",
	"Go for Beginners: A Comprehensive Guide",
	"Advanced Go Programming Techniques",
	"Testing in Go: Best Practices",
	"Go Modules: Managing Dependencies",
	"Introduction to Go Interfaces",
	"Go Data Structures and Algorithms",
	"Building CLI Applications with Go",
	"Go Memory Management",
	"Go Design Patterns",
	"Deploying Go Applications",
	"Go and Microservices",
	"Profiling and Optimizing Go Code",
}

var contents = []string{
	"Learn the basics of Go programming in just 10 days with this comprehensive guide.",
	"Understand the intricacies of concurrency in Go and how to effectively manage goroutines.",
	"Step-by-step guide to building RESTful APIs using the Go programming language.",
	"Discover tips and tricks to master Go programming and write efficient code.",
	"Compare the features and performance of Go and Python in various scenarios.",
	"Learn how to handle errors gracefully in Go and write robust applications.",
	"An in-depth explanation of goroutines and channels in Go for concurrent programming.",
	"Build a simple yet powerful web server using Go and the net/http package.",
	"A comprehensive guide for beginners to learn Go programming from scratch.",
	"Explore advanced programming techniques in Go to write high-performance applications.",
	"Best practices for writing and running tests in Go to ensure code quality.",
	"Manage dependencies in your Go projects using Go Modules effectively.",
	"An introduction to interfaces in Go and how to use them for polymorphism.",
	"Learn about various data structures and algorithms implemented in Go.",
	"Build command-line applications in Go with ease using the flag package.",
	"Understand Go's memory management and how to optimize memory usage.",
	"Explore common design patterns in Go to write maintainable and scalable code.",
	"Learn how to deploy Go applications to various environments.",
	"Discover how to build microservices architecture using Go.",
	"Techniques for profiling and optimizing the performance of Go code.",
}

var tags = []string{
	"golang", "programming", "tutorial", "webdev", "backend", "frontend", "api", "concurrency", "microservices", "testing",
	"designpatterns", "cli", "memory", "optimization", "deployment", "databases", "security", "networking", "algorithms", "datastructures",
}

var comments = []string{
	"Great post! Thanks for sharing.",
	"Very informative. I learned a lot.",
	"I disagree with some points, but overall a good read.",
	"Can you provide more details on this topic?",
	"Excellent writing! Keep it up.",
	"This helped me understand Go better. Thanks!",
	"Interesting perspective. I never thought about it that way.",
	"Could you share the source code?",
	"Looking forward to your next post.",
	"Thanks for the insights. Very helpful.",
	"Well explained. I appreciate the examples.",
	"I have a question about concurrency in Go.",
	"Can you recommend more resources on this topic?",
	"Great tips! I'll definitely try them out.",
	"This post is a bit confusing. Can you clarify?",
	"Thanks for the tutorial. It was easy to follow.",
	"I found a typo in the code snippet.",
	"Can you write about error handling in Go?",
	"Your posts are always so detailed and helpful.",
	"I tried this and it worked perfectly. Thanks!",
}

func Seed(store store.Storage, db *sql.DB) {
	ctx := context.Background()

	users := generateUsers(100)
	tx, _ := db.BeginTx(ctx, nil)

	for _, u := range users {
		if err := store.Users.Create(ctx, tx, u); err != nil {
			tx.Rollback()
			log.Println("failed to create user:", err)
		}
	}

	tx.Commit()

	posts := generatePosts(200, users)
	for _, p := range posts {
		if err := store.Posts.Create(ctx, p); err != nil {
			log.Println("failed to create post:", err)
		}
	}

	comments := generateComments(500, users, posts)
	for _, c := range comments {
		if err := store.Comments.Create(ctx, c); err != nil {
			log.Println("failed to create comment:", err)
		}
	}

	log.Println("seeded database with sample data")
}

func generateUsers(n int) []*store.User {
	users := make([]*store.User, n)
	for i := 0; i < n; i++ {
		users[i] = &store.User{
			FirstName: first_names[i%len(first_names)],
			LastName:  last_names[i%len(last_names)],
			Username:  usernames[i%len(usernames)] + fmt.Sprintf("%d", i),
			Email:     usernames[i%len(usernames)] + fmt.Sprintf("%d", i) + "@example.com",
			Role: store.Role{
				Name: "user",
			},
		}
	}
	return users
}

func generatePosts(n int, users []*store.User) []*store.Post {

	posts := make([]*store.Post, n)
	for i := 0; i < n; i++ {
		user := users[rand.Intn(len(users))]
		posts[i] = &store.Post{
			UserID:  user.ID,
			Title:   titles[rand.Intn(len(titles))],
			Content: contents[rand.Intn(len(contents))],
			Tags:    []string{tags[rand.Intn(len(tags))], tags[rand.Intn(len(tags))]},
		}
	}
	return posts
}

func generateComments(n int, users []*store.User, posts []*store.Post) []*store.Comment {
	post_comments := make([]*store.Comment, n)
	for i := 0; i < n; i++ {
		user := users[rand.Intn(len(users))]
		post := posts[rand.Intn(len(posts))]
		post_comments[i] = &store.Comment{
			PostID:  post.ID,
			UserID:  user.ID,
			Content: comments[rand.Intn(len(comments))],
		}
	}
	return post_comments
}
