import os
import shutil
import json
from pathlib import Path

from django.apps import apps
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = 'Bootstrap project after cloning: create .env, migrate, createsuperuser, collectstatic, verify Redis, seed data.'

    def handle(self, *args, **options):
        base_dir = Path(settings.BASE_DIR)
        repo_root = base_dir.parent

        env_file = repo_root / '.env'
        env_example = repo_root / '.env.example'

        # 1. Ensure .env exists
        if not env_file.exists():
            if env_example.exists():
                shutil.copy(env_example, env_file)
                self.stdout.write(self.style.SUCCESS('Created .env from .env.example'))
            else:
                self.stdout.write(self.style.WARNING('.env.example not found; create .env manually'))
        else:
            self.stdout.write('.env already exists; leaving unchanged')

        # 2. Run migrations
        self.stdout.write('Running database migrations...')
        try:
            call_command('migrate')
            self.stdout.write(self.style.SUCCESS('Migrations completed'))
        except Exception as exc:
            self.stdout.write(self.style.ERROR(f'Migrations failed: {exc}'))

        # 3. Optionally create superuser
        try:
            create = input('Create superuser now? [y/N]: ').strip().lower()
        except Exception:
            create = 'n'
        if create == 'y':
            try:
                call_command('createsuperuser')
            except Exception as exc:
                self.stdout.write(self.style.ERROR(f'createsuperuser failed: {exc}'))

        # 4. Collect static files
        self.stdout.write('Collecting static files...')
        try:
            call_command('collectstatic', '--noinput')
            self.stdout.write(self.style.SUCCESS('Collected static files'))
        except Exception as exc:
            self.stdout.write(self.style.WARNING(f'collectstatic failed or skipped: {exc}'))

        # 5. Verify Redis connection
        redis_url = os.environ.get('REDIS_URL') or getattr(settings, 'REDIS_URL', None)
        if redis_url:
            self.stdout.write(f'Verifying Redis connection: {redis_url}')
            try:
                import redis as _redis

                r = _redis.from_url(redis_url, socket_connect_timeout=2)
                pong = r.ping()
                if pong:
                    self.stdout.write(self.style.SUCCESS('Redis connection OK'))
                else:
                    self.stdout.write(self.style.WARNING('Redis ping returned false'))
            except Exception as exc:
                self.stdout.write(self.style.WARNING(f'Failed to connect to Redis: {exc}'))
        else:
            self.stdout.write('No REDIS_URL configured; skipping Redis check')

        # 6. Seed optional data (Languages, Currencies, FeatureFlags)
        self.stdout.write('Seeding optional master data (if empty)...')
        # Languages
        try:
            Language = apps.get_model('masterdata', 'Language')
            if Language.objects.exists():
                self.stdout.write('Languages already exist; skipping')
            else:
                Language.objects.create(code='en', name='English', native_name='English')
                Language.objects.create(code='es', name='Spanish', native_name='Español')
                self.stdout.write(self.style.SUCCESS('Seeded languages'))
        except LookupError:
            self.stdout.write('masterdata.Language model not available; skipping languages')
        except Exception as exc:
            self.stdout.write(self.style.WARNING(f'Failed to seed languages: {exc}'))

        # Currencies
        try:
            Currency = apps.get_model('masterdata', 'Currency')
            if Currency.objects.exists():
                self.stdout.write('Currencies already exist; skipping')
            else:
                Currency.objects.create(code='USD', name='US Dollar', symbol='$')
                Currency.objects.create(code='INR', name='Indian Rupee', symbol='₹')
                self.stdout.write(self.style.SUCCESS('Seeded currencies'))
        except LookupError:
            self.stdout.write('masterdata.Currency model not available; skipping currencies')
        except Exception as exc:
            self.stdout.write(self.style.WARNING(f'Failed to seed currencies: {exc}'))

        # Feature flags
        try:
            FeatureFlag = apps.get_model('featureflags', 'FeatureFlag')
            if FeatureFlag.objects.exists():
                self.stdout.write('Feature flags already exist; skipping')
            else:
                FeatureFlag.objects.create(name='example_feature', key='example_feature', is_active=False)
                self.stdout.write(self.style.SUCCESS('Seeded example feature flag'))
        except LookupError:
            self.stdout.write('featureflags.FeatureFlag model not available; skipping feature flags')
        except Exception as exc:
            self.stdout.write(self.style.WARNING(f'Failed to seed feature flags: {exc}'))

        # 7. Success message
        self.stdout.write(self.style.SUCCESS('Project bootstrap completed successfully.'))

        # Project metadata: write project_config.json with template info
        try:
            template_version_file = repo_root / 'TEMPLATE_VERSION'
            template_version = 'unknown'
            if template_version_file.exists():
                try:
                    template_version = template_version_file.read_text(encoding='utf-8').strip()
                except Exception:
                    template_version = 'unknown'

            project_meta = {
                'template': 'ai-project-template',
                'template_version': template_version,
            }
            project_config_path = repo_root / 'project_config.json'
            project_config_path.write_text(json.dumps(project_meta, indent=2), encoding='utf-8')
            self.stdout.write(self.style.SUCCESS(f'Wrote project metadata to {project_config_path}'))
        except Exception as exc:
            self.stdout.write(self.style.WARNING(f'Failed to write project_config.json: {exc}'))
