import random

import pytz
from django.core.management.base import BaseCommand
from faker import Faker

from api.models import Industry, Business, Product, Customer, SaleRecord, Reward, REWARDS_PRICE_TYPE

fake = Faker()


class Command(BaseCommand):
    help = 'Generates fake data for the application'

    def handle(self, *args, **options):
        # Generate fake data for the Industry model
        industries = self.generate_industries(num_records=1)

        # Generate fake data for the Business model
        businesses = self.generate_businesses(industries=industries, num_records=1)

        # Generate fake data for the Product model
        products = self.generate_products(industries=industries, num_records=20)

        # Generate fake data for the Customer model
        customers = self.generate_customers(businesses=businesses, num_records=5)

        # Generate fake data for the Customer model
        self.generate_rewards(businesses=businesses, num_records=15)

        # Generate fake data for the Rating model
        self.generate_sale_record(customers=customers, businesses=businesses, products=products, num_records=100)

        self.stdout.write(self.style.SUCCESS('Fake data generation completed successfully.'))

    # Generate fake data for the Industry model
    def generate_industries(self, num_records):
        industries_data = []
        for _ in range(num_records):
            name = fake.word()
            industry = Industry.objects.create(name=name)
            industries_data.append(industry)
        self.handle_created_at(industries_data)
        self.stdout.write(self.style.WARNING('Industries'))
        return industries_data

    # Generate fake data for the Business model
    def generate_businesses(self, industries, num_records):
        businesses_data = []
        for _ in range(num_records):
            manager_full_name = fake.name()
            country = fake.country_code()
            manager_mobile = fake.phone_number()
            name = fake.company()
            industry = random.choice(industries)
            email = fake.email()
            phone = fake.phone_number()
            address = fake.address()
            web_site = fake.url()
            instagram = fake.user_name()
            icon = None  # Add logic to generate a fake image file if needed

            business = Business.objects.create(
                manager_full_name=manager_full_name,
                country=country,
                manager_mobile=manager_mobile,
                name=name,
                industry=industry,
                email=email,
                phone=phone,
                address=address,
                web_site=web_site,
                instagram=instagram,
                icon=icon
            )
            businesses_data.append(business)
        self.handle_created_at(businesses_data)
        self.stdout.write(self.style.WARNING('business'))
        return businesses_data

    # Generate fake data for the Product model
    def generate_products(self, industries, num_records):
        products_data = []
        for _ in range(num_records):
            name = fake.word()
            industry = random.choice(industries)
            product = Product.objects.create(name=name, industry=industry)
            products_data.append(product)
        self.handle_created_at(products_data)
        self.stdout.write(self.style.WARNING('product'))
        return products_data

    # Generate fake data for the Customer model
    def generate_customers(self, businesses, num_records):
        customers_data = []
        for _ in range(num_records):
            gender = random.choice(['M', 'F'])
            dob = fake.date_of_birth(minimum_age=18, maximum_age=90)
            full_name = fake.name()
            country_code = fake.country_calling_code()
            mobile = fake.phone_number()
            email = fake.email()

            business = random.choice(businesses)
            customer = Customer.objects.create(
                country_code=country_code,
                mobile=mobile,
                full_name=full_name,
                gender=gender,
                dob=dob,
                email=email,
                business=business
            )

            customers_data.append(customer)
        self.handle_created_at(customers_data)
        self.stdout.write(self.style.WARNING('customer'))
        return customers_data

    # Generate fake data for the Rating model
    def generate_sale_record(self, customers, businesses, products, num_records):
        sale_record_data = []
        for _ in range(num_records):
            rate = random.randint(0, 10)
            description = fake.paragraph() if random.choice([True, False]) else None
            customer = random.choice(customers)
            amount = round(random.uniform(10, 1000), 2)
            delivery_date = fake.date_time_this_month(tzinfo=pytz.UTC)
            business = random.choice(businesses)
            rating = SaleRecord.objects.create(
                business=business,
                rate=rate,
                description=description,
                customer=customer,
                amount=amount,
                delivery_date=delivery_date
            )
            rating.products.set(random.choices(products, k=random.randint(0, 5)))
            sale_record_data.append(rating)
        self.handle_created_at(sale_record_data)
        self.stdout.write(self.style.WARNING('rating'))
        return sale_record_data

    # Generate fake data for the rewards model
    def generate_rewards(self, businesses, num_records):
        rewards_data = []
        for _ in range(num_records):
            name = fake.word()
            description = fake.sentence()
            price = random.randint(1, 1000)
            price_type = random.choice([choice[0] for choice in REWARDS_PRICE_TYPE])
            # start_date = fake.date_between(start_date="-30d", end_date="30d")
            # end_date = fake.date_between(start_date=start_date, end_date="90d")
            capacity = random.randint(0, 100)
            is_reusable = fake.boolean(chance_of_getting_true=50)
            is_enabled = fake.boolean(chance_of_getting_true=90)

            business = random.choice(businesses)
            reward = Reward.objects.create(
                business=business,
                name=name,
                description=description,
                price=price,
                price_type=price_type,
                # start_date=start_date,
                # end_date=end_date,
                capacity=capacity,
                is_reusable=is_reusable,
                is_enabled=is_enabled,
            )

            rewards_data.append(reward)
        self.handle_created_at(rewards_data)
        self.stdout.write(self.style.WARNING('reward'))
        return rewards_data

    def handle_created_at(self, records):
        for i in records:
            i.created_at = fake.date_time_this_month(tzinfo=pytz.UTC)
            i.updated_at = fake.date_time_this_month(tzinfo=pytz.UTC)
            i.save()
