import os
import random
import zipfile
from datetime import datetime, timedelta

import numpy as np
import pandas as pd

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

INDUSTRIES = [
    'Retail',
    'Banking',
    'Telecom',
    'Healthcare',
    'E-commerce',
]

REGIONS = [
    {'region': 'North', 'cities': ['Hà Nội', 'Hải Phòng', 'Bắc Ninh', 'Hải Dương']},
    {'region': 'Central', 'cities': ['Đà Nẵng', 'Huế', 'Nha Trang', 'Quy Nhơn']},
    {'region': 'South', 'cities': ['TP.HCM', 'Cần Thơ', 'Bình Dương', 'Đồng Nai']},
]

PRODUCT_CATEGORIES = [
    ('Thực phẩm', 'Sữa & Đồ uống'),
    ('Thực phẩm', 'Snack & Đồ ăn nhanh'),
    ('Chăm sóc cá nhân', 'Dầu gội & Sữa tắm'),
    ('Mỹ phẩm', 'Trang điểm'),
    ('Điện tử', 'Tai nghe & Loa'),
    ('Thời trang', 'Giày dép'),
    ('Đồ gia dụng', 'Đồ bếp'),
]

BRANDS = [
    'Vinamilk', 'TH True Milk', 'Unilever', 'P&G', 'Samsung', 'Apple', 'Xiaomi',
    'OPPO', 'L’Oreal', 'Maybelline', 'Nestle', 'Coca-Cola', 'Kinh Đô', 'Lock&Lock',
    'Panasonic', 'Sony', 'Adidas', 'Nike', 'JBL', 'Lifebuoy'
]

CUSTOMER_SEGMENTS = ['Standard', 'Bronze', 'Silver', 'Gold', 'Platinum']
GENDERS = ['Nam', 'Nữ']
PAYMENT_METHODS = ['Cash', 'Credit Card', 'E-wallet', 'Bank Transfer']
WORKFLOW_STATUSES = ['success', 'failed', 'running']
SOCIAL_PLATFORMS = ['Facebook', 'Instagram', 'LinkedIn', 'TikTok', 'Email']
CAMPAIGN_OBJECTIVES = ['Brand Awareness', 'Lead Generation', 'Sales', 'Retention', 'Launch']
CONTENT_TONES = ['Chuyên nghiệp', 'Thân thiện', 'Hấp dẫn', 'Thuyết phục', 'Giải trí']


def make_customers(n_customers=5000):
    customers = []
    for i in range(1, n_customers + 1):
        region_info = random.choice(REGIONS)
        city = random.choice(region_info['cities'])
        age = random.randint(18, 65)
        industry = random.choice(INDUSTRIES)
        segment = random.choices(CUSTOMER_SEGMENTS, weights=[45, 25, 15, 10, 5], k=1)[0]
        registration_date = datetime(2021, 1, 1) + timedelta(days=random.randint(0, 730))
        first_purchase_date = registration_date + timedelta(days=random.randint(0, 90))
        customers.append({
            'customer_id': f'CUST{str(i).zfill(5)}',
            'full_name': f'Khách hàng {i}',
            'gender': random.choice(GENDERS),
            'age': age,
            'age_group': f'{(age // 10) * 10}-{(age // 10) * 10 + 9}',
            'phone_prefix': random.choice(['090', '091', '092', '093', '094', '095', '096', '097', '098', '099']),
            'email_domain': random.choice(['gmail.com', 'yahoo.com', 'vng.com', 'fpt.com', 'vnpt.vn']),
            'city': city,
            'region': region_info['region'],
            'industry': industry,
            'customer_segment': segment,
            'loyalty_points': random.randint(0, 20000),
            'registration_date': registration_date.date(),
            'first_purchase_date': first_purchase_date.date(),
            'is_active': random.choices([True, False], weights=[0.85, 0.15], k=1)[0],
        })
    return pd.DataFrame(customers)


def make_products(n_products=500):
    products = []
    for i in range(1, n_products + 1):
        category, subcategory = random.choice(PRODUCT_CATEGORIES)
        brand = random.choice(BRANDS)
        industry = random.choice(INDUSTRIES)
        unit_cost = random.randint(10000, 200000)
        unit_price = int(unit_cost * random.uniform(1.1, 2.5))
        products.append({
            'product_id': f'PROD{str(i).zfill(5)}',
            'product_name': f'{brand} {subcategory} {i}',
            'category': category,
            'subcategory': subcategory,
            'brand': brand,
            'industry': industry,
            'unit_price': unit_price,
            'unit_cost': unit_cost,
            'profit_margin': round((unit_price - unit_cost) / unit_price * 100, 2),
            'unit_of_measure': random.choice(['Cái', 'Hộp', 'Chai', 'Bộ', 'Chiếc']),
            'country_origin': random.choice(['Việt Nam', 'Nhật Bản', 'Hàn Quốc', 'Mỹ', 'Trung Quốc']),
            'launch_date': (datetime(2020, 1, 1) + timedelta(days=random.randint(0, 1500))).date(),
            'is_active': True,
        })
    return pd.DataFrame(products)


def make_stores(n_stores=50):
    stores = []
    for i in range(1, n_stores + 1):
        region_info = random.choice(REGIONS)
        city = random.choice(region_info['cities'])
        stores.append({
            'store_id': f'ST{str(i).zfill(3)}',
            'store_name': f'Chi nhánh {city} {i}',
            'region': region_info['region'],
            'city': city,
            'store_type': random.choice(['Store', 'Branch', 'Outlet', 'Mini-store']),
            'opened_date': (datetime(2018, 1, 1) + timedelta(days=random.randint(0, 2000))).date(),
            'is_flagship': random.choice([True, False]),
        })
    return pd.DataFrame(stores)


def make_transactions(customers, products, stores, n_transactions=50000):
    transactions = []
    start_date = datetime(2023, 1, 1)
    for i in range(1, n_transactions + 1):
        customer = customers.sample(1).iloc[0]
        product = products.sample(1).iloc[0]
        store = stores.sample(1).iloc[0]
        transaction_date = start_date + timedelta(days=random.randint(0, 729))
        quantity = random.randint(1, 10)
        discount_percent = random.choice([0, 0, 5, 10, 15])
        total_amount = int(product['unit_price'] * quantity * (1 - discount_percent / 100))
        transactions.append({
            'transaction_id': f'TXN{str(i).zfill(6)}',
            'customer_id': customer['customer_id'],
            'product_id': product['product_id'],
            'store_id': store['store_id'],
            'transaction_date': transaction_date.date(),
            'industry': random.choice([customer['industry'], product['industry'], store['region']]),
            'region': store['region'],
            'city': store['city'],
            'quantity': quantity,
            'unit_price': product['unit_price'],
            'discount_percent': discount_percent,
            'total_amount': total_amount,
            'payment_method': random.choice(PAYMENT_METHODS),
            'is_returned': random.choices([False, True], weights=[0.95, 0.05], k=1)[0],
        })
    return pd.DataFrame(transactions)


def save_and_zip(dataframes, folder_name, zip_name):
    output_dir = os.path.join(BASE_DIR, folder_name)
    os.makedirs(output_dir, exist_ok=True)

    for filename, df in dataframes.items():
        df.to_csv(os.path.join(output_dir, filename), index=False)

    zip_path = os.path.join(BASE_DIR, zip_name)
    with zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED) as archive:
        for filename in dataframes.keys():
            archive.write(os.path.join(output_dir, filename), arcname=os.path.join(folder_name, filename))

    print(f'Generated {zip_path}')
    return output_dir, zip_path


def make_business_analytics_data():
    customers = make_customers(n_customers=2000)
    products = make_products(n_products=300)
    sales = []
    start_date = datetime(2023, 1, 1)

    for i in range(1, 15001):
        customer = customers.sample(1).iloc[0]
        product = products.sample(1).iloc[0]
        transaction_date = start_date + timedelta(days=random.randint(0, 729))
        quantity = random.randint(1, 10)
        discount_percent = random.choice([0, 0, 5, 10])
        total_amount = int(product['unit_price'] * quantity * (1 - discount_percent / 100))
        sales.append({
            'sale_id': f'SALE{str(i).zfill(6)}',
            'customer_id': customer['customer_id'],
            'product_id': product['product_id'],
            'transaction_date': transaction_date.date(),
            'region': customer['region'],
            'city': customer['city'],
            'industry': customer['industry'],
            'quantity': quantity,
            'unit_price': product['unit_price'],
            'discount_percent': discount_percent,
            'total_amount': total_amount,
            'payment_method': random.choice(PAYMENT_METHODS),
        })

    sales_df = pd.DataFrame(sales)
    return {
        'customers.csv': customers,
        'products.csv': products,
        'sales.csv': sales_df,
    }


def make_ml_playground_data():
    churn = []
    for i in range(1, 8001):
        age = random.randint(18, 80)
        tenure = random.randint(1, 72)
        monthly = random.randint(200, 3000)
        churn.append({
            'customer_id': f'CHURN{str(i).zfill(5)}',
            'age': age,
            'gender': random.choice(GENDERS),
            'tenure_months': tenure,
            'monthly_charges': monthly,
            'total_charges': round(monthly * tenure * random.uniform(0.9, 1.1), 2),
            'churn': random.choices([0, 1], weights=[0.75, 0.25], k=1)[0],
        })

    houses = []
    locations = ['Hà Nội', 'TP.HCM', 'Đà Nẵng', 'Nha Trang', 'Huế', 'Cần Thơ']
    for i in range(1, 5001):
        bedrooms = random.randint(1, 5)
        bathrooms = random.randint(1, 3)
        area = random.randint(30, 250)
        year = random.randint(1990, 2024)
        price = int(area * random.randint(2000, 6000) * (1 + (bedrooms - 1) * 0.1))
        houses.append({
            'house_id': f'HOUSE{str(i).zfill(5)}',
            'location': random.choice(locations),
            'bedrooms': bedrooms,
            'bathrooms': bathrooms,
            'area_sqft': area,
            'year_built': year,
            'price': price,
        })

    reviews = []
    sentiments = ['positive', 'neutral', 'negative']
    topics = ['electronics', 'food', 'fashion', 'travel', 'health']
    for i in range(1, 12001):
        sentiment = random.choices(sentiments, weights=[0.55, 0.25, 0.2], k=1)[0]
        reviews.append({
            'review_id': f'REV{str(i).zfill(5)}',
            'product_id': f'PROD{str(random.randint(1, 300)).zfill(5)}',
            'rating': random.randint(1, 5),
            'review_text': f'This {random.choice(topics)} product is {"great" if sentiment == "positive" else "okay" if sentiment == "neutral" else "disappointing"}.',
            'review_date': (datetime(2023, 1, 1) + timedelta(days=random.randint(0, 729))).date(),
            'sentiment': sentiment,
        })

    return {
        'customer_churn.csv': pd.DataFrame(churn),
        'house_prices.csv': pd.DataFrame(houses),
        'product_reviews.csv': pd.DataFrame(reviews),
    }


def make_genai_document_corpus_data():
    kb = []
    domains = ['Sales', 'Support', 'HR', 'Finance', 'Product']
    for i in range(1, 7501):
        domain = random.choice(domains)
        kb.append({
            'doc_id': f'KB{str(i).zfill(5)}',
            'title': f'{domain} best practice {i}',
            'content': f'Nội dung tài liệu {i} về {domain} với các quy trình và hướng dẫn.',
            'domain': domain,
            'source': random.choice(['Internal', 'Public Web', 'Partner', 'Research']),
        })

    chat = []
    roles = ['user', 'assistant']
    for i in range(1, 5001):
        chat.append({
            'chat_id': f'CHAT{str(i).zfill(5)}',
            'user_id': f'USER{str(random.randint(1, 2000)).zfill(4)}',
            'timestamp': (datetime(2023, 1, 1) + timedelta(days=random.randint(0, 729), seconds=random.randint(0, 86399))).isoformat(),
            'role': random.choice(roles),
            'message': f'Message {i} về {random.choice(domains)}.',
        })

    faq = []
    for i in range(1, 1201):
        topic = random.choice(domains)
        faq.append({
            'faq_id': f'FAQ{str(i).zfill(4)}',
            'question': f'Làm sao để giải quyết vấn đề {topic.lower()} {i}?',
            'answer': f'Trả lời cho câu hỏi về {topic.lower()} trong ngữ cảnh doanh nghiệp.',
            'topic': topic,
        })

    return {
        'knowledge_base.csv': pd.DataFrame(kb),
        'chat_logs.csv': pd.DataFrame(chat),
        'faq_pairs.csv': pd.DataFrame(faq),
    }


def make_content_creator_library_data():
    templates = []
    industries = ['Marketing', 'Retail', 'Education', 'Finance', 'Travel']
    for i in range(1, 1201):
        templates.append({
            'template_id': f'TEMP{str(i).zfill(5)}',
            'content_type': random.choice(['Email', 'Post', 'Ad', 'Landing Page']),
            'industry': random.choice(industries),
            'tone': random.choice(CONTENT_TONES),
            'template_text': f'Ví dụ template nội dung {i} cho {random.choice(industries)}.',
        })

    briefs = []
    for i in range(1, 801):
        briefs.append({
            'brief_id': f'BRIEF{str(i).zfill(4)}',
            'campaign_name': f'Chiến dịch {i}',
            'objective': random.choice(CAMPAIGN_OBJECTIVES),
            'target_audience': random.choice(['Gen Z', 'Millennials', 'Doanh nghiệp vừa và nhỏ', 'Khách hàng cao cấp']),
            'channel': random.choice(['Facebook', 'Instagram', 'Email', 'TikTok', 'LinkedIn']),
            'budget': random.randint(5000000, 50000000),
        })

    posts = []
    for i in range(1, 1501):
        posts.append({
            'post_id': f'POST{str(i).zfill(4)}',
            'platform': random.choice(SOCIAL_PLATFORMS),
            'topic': random.choice(['Launch', 'Promotion', 'Storytelling', 'Tips', 'Event']),
            'post_text': f'Nội dung bài đăng {i} cho {random.choice(SOCIAL_PLATFORMS)} về {random.choice(['xu hướng', 'khuyến mãi', 'sản phẩm'])}.',
            'scheduled_date': (datetime(2024, 1, 1) + timedelta(days=random.randint(0, 365))).date(),
        })

    return {
        'content_templates.csv': pd.DataFrame(templates),
        'campaign_briefs.csv': pd.DataFrame(briefs),
        'social_posts.csv': pd.DataFrame(posts),
    }


def make_automation_event_logs_data():
    events = []
    for i in range(1, 18001):
        workflow_id = f'WF{str(random.randint(1, 120)).zfill(3)}'
        start_time = datetime(2024, 1, 1) + timedelta(days=random.randint(0, 180), seconds=random.randint(0, 86399))
        duration = random.randint(100, 20000)
        events.append({
            'event_id': f'EVENT{str(i).zfill(6)}',
            'timestamp': start_time.isoformat(),
            'workflow_id': workflow_id,
            'step_name': random.choice(['start', 'validate', 'transform', 'send', 'complete']),
            'status': random.choice(WORKFLOW_STATUSES),
            'duration_ms': duration,
            'payload_type': random.choice(['JSON', 'XML', 'CSV', 'Webhook']),
            'error_code': random.choice(['', 'ERR001', 'ERR002', 'ERR_TIMEOUT']),
        })

    connections = []
    services = ['Salesforce', 'Google Sheets', 'Slack', 'Email', 'Stripe']
    for i in range(1, 121):
        connections.append({
            'connection_id': f'CONN{str(i).zfill(4)}',
            'service_name': random.choice(services),
            'status': random.choice(['active', 'inactive']),
            'last_tested': (datetime(2024, 1, 1) + timedelta(days=random.randint(0, 180))).date(),
            'auth_type': random.choice(['API Key', 'OAuth2', 'Basic Auth']),
            'region': random.choice(['Vietnam', 'APAC', 'Global']),
        })

    task_runs = []
    for i in range(1, 8501):
        start_at = datetime(2024, 1, 1) + timedelta(days=random.randint(0, 180), seconds=random.randint(0, 86399))
        duration = random.randint(100, 15000)
        task_runs.append({
            'task_run_id': f'TASK{str(i).zfill(5)}',
            'workflow_id': f'WF{str(random.randint(1, 120)).zfill(3)}',
            'task_name': random.choice(['FetchData', 'Transform', 'SendNotification', 'Archive', 'Retry']),
            'started_at': start_at.isoformat(),
            'ended_at': (start_at + timedelta(milliseconds=duration)).isoformat(),
            'status': random.choice(['success', 'failed', 'running']),
            'attempt': random.randint(1, 3),
            'duration_ms': duration,
        })

    return {
        'event_logs.csv': pd.DataFrame(events),
        'integration_connections.csv': pd.DataFrame(connections),
        'task_runs.csv': pd.DataFrame(task_runs),
    }


def main():
    dataset_generators = [
        ('minai_business_analytics_starter_dataset', 'minai_business_analytics_starter_dataset.zip', make_business_analytics_data),
        ('minai_ml_playground_dataset', 'minai_ml_playground_dataset.zip', make_ml_playground_data),
        ('minai_genai_document_corpus_dataset', 'minai_genai_document_corpus_dataset.zip', make_genai_document_corpus_data),
        ('minai_content_creator_library_dataset', 'minai_content_creator_library_dataset.zip', make_content_creator_library_data),
        ('minai_automation_event_logs_dataset', 'minai_automation_event_logs_dataset.zip', make_automation_event_logs_data),
        ('minai_da_industry_dataset', 'minai_da_industry_dataset.zip', lambda: {
            'customers.csv': make_customers(n_customers=5000),
            'products.csv': make_products(n_products=500),
            'stores.csv': make_stores(n_stores=50),
            'transactions.csv': make_transactions(make_customers(n_customers=5000), make_products(n_products=500), make_stores(n_stores=50), n_transactions=50000),
        }),
    ]

    for folder_name, zip_name, generator in dataset_generators:
        print(f'Generating {folder_name}...')
        dataframes = generator()
        save_and_zip(dataframes, folder_name, zip_name)

    print('All datasets generated successfully.')


if __name__ == '__main__':
    main()
