# import json
# import pandas as pd
# from django.core.management.base import BaseCommand
# from core.models import Product, CategoryAttributeRule, ProductContentRule

# class Command(BaseCommand):
#     help = 'Load sample data (rules + products) from an Excel file'

#     def add_arguments(self, parser):
#         parser.add_argument('excel_path', type=str, help='Path to the Excel file')

#     def handle(self, *args, **options):
#         excel_path = options['excel_path']
#         self.stdout.write(self.style.NOTICE(f"📂 Reading Excel: {excel_path}"))

#         # Load sheets
#         try:
#             xls = pd.ExcelFile(excel_path)
#         except Exception as e:
#             self.stdout.write(self.style.ERROR(f"Failed to read Excel file: {e}"))
#             return

#         # --- Load Category Rules ---
#         if 'category_rules' in xls.sheet_names:
#             df = pd.read_excel(xls, 'category_rules').fillna('')
#             CategoryAttributeRule.objects.all().delete()
#             for _, row in df.iterrows():
#                 valid_values = self._parse_json(row.get('valid_values', '[]'))
#                 CategoryAttributeRule.objects.create(
#                     category=row['category'],
#                     attribute_name=row['attribute_name'],
#                     is_mandatory=bool(row['is_mandatory']),
#                     valid_values=valid_values,
#                     data_type=row.get('data_type', 'string'),
#                     validation_regex=row.get('validation_regex', ''),
#                     min_length=row.get('min_length') or None,
#                     max_length=row.get('max_length') or None,
#                     description=row.get('description', '')
#                 )
#             self.stdout.write(self.style.SUCCESS(f"✅ Loaded {len(df)} category rules"))
#         else:
#             self.stdout.write(self.style.WARNING("⚠️ Sheet 'category_rules' not found."))

#         # --- Load Content Rules ---
#         if 'content_rules' in xls.sheet_names:
#             df = pd.read_excel(xls, 'content_rules').fillna('')
#             ProductContentRule.objects.all().delete()
#             for _, row in df.iterrows():
#                 keywords = self._parse_json(row.get('must_contain_keywords', '[]'))
#                 ProductContentRule.objects.create(
#                     category=row.get('category') or None,
#                     field_name=row['field_name'],
#                     is_mandatory=bool(row['is_mandatory']),
#                     min_length=row.get('min_length') or None,
#                     max_length=row.get('max_length') or None,
#                     min_word_count=row.get('min_word_count') or None,
#                     max_word_count=row.get('max_word_count') or None,
#                     must_contain_keywords=keywords,
#                     validation_regex=row.get('validation_regex', ''),
#                     description=row.get('description', '')
#                 )
#             self.stdout.write(self.style.SUCCESS(f"✅ Loaded {len(df)} content rules"))
#         else:
#             self.stdout.write(self.style.WARNING("⚠️ Sheet 'content_rules' not found."))

#         # --- Load Products ---
#         if 'products' in xls.sheet_names:
#             df = pd.read_excel(xls, 'products').fillna('')
#             Product.objects.all().delete()
#             for _, row in df.iterrows():
#                 attrs = self._parse_json(row.get('attributes', '{}'))
#                 Product.objects.create(
#                     sku=row['sku'],
#                     category=row['category'],
#                     title=row['title'],
#                     description=row.get('description', ''),
#                     seo_title=row.get('seo_title', ''),
#                     seo_description=row.get('seo_description', ''),
#                     attributes=attrs
#                 )
#             self.stdout.write(self.style.SUCCESS(f"✅ Loaded {len(df)} products"))
#         else:
#             self.stdout.write(self.style.WARNING("⚠️ Sheet 'products' not found."))

#         self.stdout.write(self.style.SUCCESS("🎯 Excel data loaded successfully!"))

#     def _parse_json(self, value):
#         """Safely parse JSON or comma-separated values."""
#         if isinstance(value, list):
#             return value
#         if isinstance(value, str) and value.strip():
#             try:
#                 return json.loads(value)
#             except json.JSONDecodeError:
#                 # Maybe comma-separated
#                 return [v.strip() for v in value.split(',') if v.strip()]
#         return []





import json
import pandas as pd
from django.core.management.base import BaseCommand
from core.models import Product, CategoryAttributeRule, ProductContentRule
from django.db import transaction

class Command(BaseCommand):
    help = 'Load sample data (rules + products) from an Excel file, only inserting new records or updating existing ones.'

    def add_arguments(self, parser):
        parser.add_argument('excel_path', type=str, help='Path to the Excel file')

    def handle(self, *args, **options):
        excel_path = options['excel_path']
        self.stdout.write(self.style.NOTICE(f"📂 Reading Excel: {excel_path}"))

        # Initialize counters
        loaded_counts = {
            'category_rules': 0,
            'content_rules': 0,
            'products': 0,
        }
        output_messages = []

        # Load sheets
        try:
            xls = pd.ExcelFile(excel_path)
        except Exception as e:
            self.stdout.write(self.style.ERROR(f"Failed to read Excel file: {e}"))
            # In the API context, this needs to be returned as an error response
            return {'error': f"Failed to read Excel file: {e}"}

        # --- Load Category Rules (Upsert) ---
        if 'category_rules' in pd.ExcelFile(excel_path).sheet_names:
            df = pd.read_excel(excel_path, 'category_rules').fillna('')
            count = 0
            # Use transaction.atomic for better database performance
            with transaction.atomic():
                for _, row in df.iterrows():
                    valid_values = self._parse_json(row.get('valid_values', '[]'))
                    
                    # Define unique key for CategoryAttributeRule
                    unique_key = {
                        'category': row['category'],
                        'attribute_name': row['attribute_name'],
                    }
                    
                    # Define fields that can be updated
                    update_fields = {
                        'is_mandatory': bool(row['is_mandatory']),
                        'valid_values': valid_values,
                        'data_type': row.get('data_type', 'string'),
                        'validation_regex': row.get('validation_regex', ''),
                        'min_length': row.get('min_length') or None,
                        'max_length': row.get('max_length') or None,
                        'description': row.get('description', '')
                    }
                    
                    # update_or_create performs a lookup and either updates or creates
                    # it returns (object, created)
                    _, created = CategoryAttributeRule.objects.update_or_create(
                        **unique_key,
                        defaults=update_fields
                    )
                    
                    if created:
                        count += 1

            loaded_counts['category_rules'] = count
            output_messages.append(f"✅ Loaded {count} category rules")
        else:
            self.stdout.write(self.style.WARNING("⚠️ Sheet 'category_rules' not found."))

        # --- Load Content Rules (Upsert) ---
        if 'content_rules' in xls.sheet_names:
            df = pd.read_excel(xls, 'content_rules').fillna('')
            count = 0
            with transaction.atomic():
                for _, row in df.iterrows():
                    keywords = self._parse_json(row.get('must_contain_keywords', '[]'))
                    
                    # Define unique key for ProductContentRule
                    # Assuming field_name is always unique within a category, or globally if category is None
                    unique_key = {
                        'category': row.get('category') or None,
                        'field_name': row['field_name'],
                    }
                    
                    update_fields = {
                        'is_mandatory': bool(row['is_mandatory']),
                        'min_length': row.get('min_length') or None,
                        'max_length': row.get('max_length') or None,
                        'min_word_count': row.get('min_word_count') or None,
                        'max_word_count': row.get('max_word_count') or None,
                        'must_contain_keywords': keywords,
                        'validation_regex': row.get('validation_regex', ''),
                        'description': row.get('description', '')
                    }
                    
                    _, created = ProductContentRule.objects.update_or_create(
                        **unique_key,
                        defaults=update_fields
                    )
                    
                    if created:
                        count += 1

            loaded_counts['content_rules'] = count
            output_messages.append(f"✅ Loaded {count} content rules")
        else:
            self.stdout.write(self.style.WARNING("⚠️ Sheet 'content_rules' not found."))

        # --- Load Products (Upsert based on SKU) ---
        if 'products' in xls.sheet_names:
            df = pd.read_excel(xls, 'products').fillna('')
            count = 0
            with transaction.atomic():
                for _, row in df.iterrows():
                    attrs = self._parse_json(row.get('attributes', '{}'))
                    
                    # Define unique key for Product (assuming SKU is unique)
                    unique_key = {'sku': row['sku']}
                    
                    update_fields = {
                        'category': row['category'],
                        'image_path': row['image_path'],
                        'title': row['title'],
                        'description': row.get('description', ''),
                        'seo_title': row.get('seo_title', ''),
                        'seo_description': row.get('seo_description', ''),
                        'attributes': attrs
                    }
                    
                    _, created = Product.objects.update_or_create(
                        **unique_key,
                        defaults=update_fields
                    )
                    
                    if created:
                        count += 1
            
            loaded_counts['products'] = count
            output_messages.append(f"✅ Loaded {count} products")
        else:
            self.stdout.write(self.style.WARNING("⚠️ Sheet 'products' not found."))

        output_messages.append("🎯 Excel data loaded successfully!")
        
        # Prepare the final output message string for the API response
        final_message = "\n".join(output_messages)
        
        self.stdout.write(self.style.SUCCESS(final_message))
        
        # Return the final message to be used by the APIView
        return {'success': True, 'message': final_message}

    def _parse_json(self, value):
        """Safely parse JSON or comma-separated values."""
        # ... (Your existing _parse_json method remains the same)
        if isinstance(value, list):
            return value
        if isinstance(value, str) and value.strip():
            try:
                return json.loads(value)
            except json.JSONDecodeError:
                # Maybe comma-separated
                return [v.strip() for v in value.split(',') if v.strip()]
        return []