# ==============================#
# SCHOOL MANAGEMENT VIEWS       #
# ==============================#
import uuid
import psycopg
from psycopg import sql
import json
from django.contrib.auth.models import User, Group
from django.db import transaction  # <-- THIS IS CRITICAL
import logging
from django.conf import settings
from django.db.models import Q, Count, Sum, Avg, Max, Min
from django.utils import timezone
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import viewsets, permissions, filters, status
from rest_framework.decorators import action
from .models import UserProfile

from .models import (
    School,
    SchoolType,
    SchoolBoard,
    SchoolModule,
    SchoolModuleAccess,
    Language,
)
from .serializers import (
    SchoolSerializer,
    SchoolTypeSerializer,
    SchoolBoardSerializer,
    SchoolModuleSerializer,
    LanguageSerializer,
)

logger = logging.getLogger(__name__)


class SchoolViewSet(viewsets.ModelViewSet):
    """
    ViewSet for managing schools with filtering and search capabilities.
    """

    queryset = School.objects.all().order_by("-created_at")
    serializer_class = SchoolSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]

    search_fields = [
        "name",
        "slug",
        "domain_name",
        "email",
        "phone",
        "registration_number",
        "affiliation_number",
    ]

    ordering_fields = [
        "name",
        "created_at",
        "updated_at",
        "established_year",
        "trial_ends_at",
    ]

    def get_queryset(self):
        """
        Filter schools based on query parameters.
        """
        queryset = super().get_queryset()

        # Status filter - used by your tabs
        status_param = self.request.query_params.get("status")
        if status_param:
            today = timezone.now().date()
            if status_param == "pending":
                queryset = queryset.filter(verified_at__isnull=True)
            elif status_param == "verified":
                queryset = queryset.filter(verified_at__isnull=False)
            elif status_param == "trial":
                queryset = queryset.filter(is_trial=True)
            elif status_param == "active":
                queryset = queryset.filter(is_active=True)
            elif status_param == "inactive":
                queryset = queryset.filter(is_active=False)
            elif status_param == "expired_trial":
                queryset = queryset.filter(is_trial=True, trial_ends_at__lt=today)

        # Search filter - used by your search box
        search = self.request.query_params.get("search")
        if search:
            queryset = queryset.filter(
                Q(name__icontains=search)
                | Q(email__icontains=search)
                | Q(domain_name__icontains=search)
                | Q(phone__icontains=search)
                | Q(registration_number__icontains=search)
                | Q(affiliation_number__icontains=search)
            )

        return queryset

    @action(detail=False, methods=["get"])
    def stats(self, request):
        """
        Get statistics about schools.
        Used by your JSX stats cards and tabs.
        """
        total = School.objects.count()
        pending = School.objects.filter(verified_at__isnull=True).count()
        verified = School.objects.filter(verified_at__isnull=False).count()
        active = School.objects.filter(is_active=True).count()
        trial = School.objects.filter(is_trial=True).count()
        today = timezone.now().date()
        expired_trial = School.objects.filter(
            is_trial=True, trial_ends_at__lt=today
        ).count()

        return Response(
            {
                "total": total,
                "pending": pending,
                "verified": verified,
                "active": active,
                "trial": trial,
                "expired_trial": expired_trial,
            }
        )

    @action(detail=True, methods=["post"])
    def verify(self, request, pk=None):
        """
        Verify a school.
        Used by your "Verify School" dialog.
        """
        school = self.get_object()

        if school.verified_at:
            return Response(
                {"error": "School is already verified"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        school.verified_at = timezone.now()
        school.verified_by = request.user
        school.save()

        logger.info(f"School {school.name} verified by {request.user.username}")

        return Response(
            {
                "message": "School verified successfully",
                "verified_at": school.verified_at,
                "verified_by": request.user.username,
            }
        )

    @action(detail=True, methods=["post"])
    def activate(self, request, pk=None):
        """
        Activate a school.
        Used by your "Activate School" dialog.
        """
        school = self.get_object()

        if school.is_active:
            return Response(
                {"error": "School is already active"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        school.is_active = True
        school.save()

        logger.info(f"School {school.name} activated by {request.user.username}")

        return Response({"message": "School activated successfully", "is_active": True})

    @action(detail=True, methods=["post"])
    def deactivate(self, request, pk=None):
        """
        Deactivate a school.
        Used by your "Deactivate School" dialog.
        """
        school = self.get_object()

        if not school.is_active:
            return Response(
                {"error": "School is already inactive"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        school.is_active = False
        school.save()

        logger.info(f"School {school.name} deactivated by {request.user.username}")

        return Response(
            {"message": "School deactivated successfully", "is_active": False}
        )

    @action(detail=True, methods=["post"])
    def extend_trial(self, request, pk=None):
        """
        Extend trial period for a school.
        Used by your "Extend Trial" dialog.
        """
        school = self.get_object()
        days = request.data.get("days", 7)

        try:
            days = int(days)
            if days <= 0:
                raise ValueError
        except (ValueError, TypeError):
            return Response(
                {"error": "Days must be a positive integer"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        if school.trial_ends_at:
            new_end_date = school.trial_ends_at + timezone.timedelta(days=days)
        else:
            new_end_date = timezone.now() + timezone.timedelta(days=days)

        school.trial_ends_at = new_end_date
        school.save()

        logger.info(
            f"Trial extended for school {school.name} by {days} days by {request.user.username}"
        )

        return Response(
            {
                "message": f"Trial extended by {days} days",
                "new_trial_ends_at": school.trial_ends_at,
            }
        )

    @action(detail=True, methods=["get", "post"])
    def modules(self, request, pk=None):
        """
        GET: Return all modules with is_enabled state for this school.
        POST: Update module access. Expects { module_codes: ['attendance', 'fee', ...] }
        """
        school = self.get_object()

        if request.method == "GET":
            all_modules = SchoolModule.objects.filter(is_active=True)
            access_map = {
                a.module_id: a.is_enabled
                for a in school.module_access.select_related("module")
            }
            data = [
                {
                    "id": m.id,
                    "code": m.code,
                    "name": m.name,
                    "description": m.description,
                    "icon": m.icon,
                    "order": m.order,
                    "is_default": m.is_default,
                    "is_enabled": m.is_default or access_map.get(m.id, False),
                }
                for m in all_modules
            ]
            return Response(data)

        # POST — bulk update
        enabled_codes = request.data.get("module_codes", [])
        non_default_modules = SchoolModule.objects.filter(is_active=True, is_default=False)
        for module in non_default_modules:
            SchoolModuleAccess.objects.update_or_create(
                school=school,
                module=module,
                defaults={
                    "is_enabled": module.code in enabled_codes,
                    "enabled_by": request.user,
                },
            )
        logger.info(
            f"Module access updated for {school.name} by {request.user.username}: {enabled_codes}"
        )
        return Response({"message": "Module access updated successfully"})


class LanguageViewSet(viewsets.ModelViewSet):
    """CRUD for the Language catalog (master admin only)"""

    queryset = Language.objects.all()
    serializer_class = LanguageSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["code", "name", "native_name"]
    ordering_fields = ["order", "name", "is_active"]


class SchoolModuleViewSet(viewsets.ModelViewSet):
    """CRUD for the SchoolModule catalog (master admin only)"""

    queryset = SchoolModule.objects.all()
    serializer_class = SchoolModuleSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["code", "name", "description"]
    ordering_fields = ["order", "name", "is_active"]


class SchoolBoardViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for SchoolBoard model
    """

    queryset = SchoolBoard.objects.all().order_by("sort_order", "name")
    serializer_class = SchoolBoardSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["code", "name", "board_type", "description", "website"]
    ordering_fields = ["name", "code", "sort_order", "is_active", "board_type"]

    def get_queryset(self):
        """Filter school boards based on query parameters"""
        queryset = super().get_queryset()

        # Filter by board type
        board_type = self.request.query_params.get("board_type")
        if board_type:
            queryset = queryset.filter(board_type=board_type)

        # Filter by country
        country_code = self.request.query_params.get("country_code")
        if country_code:
            queryset = queryset.filter(country__code=country_code)

        # Filter by active status
        active_only = self.request.query_params.get("active_only", "true")
        if active_only.lower() == "true":
            queryset = queryset.filter(is_active=True)

        # Filter by streams availability
        has_streams = self.request.query_params.get("has_streams")
        if has_streams:
            has_streams_bool = has_streams.lower() == "true"
            queryset = queryset.filter(has_streams=has_streams_bool)

        # Filter by elective subjects
        has_electives = self.request.query_params.get("has_electives")
        if has_electives:
            has_electives_bool = has_electives.lower() == "true"
            queryset = queryset.filter(has_elective_subjects=has_electives_bool)

        return queryset

    @action(detail=False, methods=["get"])
    def stats(self, request):
        """Get statistics about school boards"""
        total = SchoolBoard.objects.count()
        active = SchoolBoard.objects.filter(is_active=True).count()

        # Count by board type
        board_type_stats = (
            SchoolBoard.objects.values("board_type")
            .annotate(count=Count("id"))
            .order_by("-count")
        )

        # Count by country
        country_stats = (
            SchoolBoard.objects.filter(country__isnull=False)
            .values("country__code", "country__name")
            .annotate(count=Count("id"))
            .order_by("-count")
        )

        # Count with streams
        with_streams = SchoolBoard.objects.filter(has_streams=True).count()
        with_electives = SchoolBoard.objects.filter(has_elective_subjects=True).count()

        return Response(
            {
                "total": total,
                "active": active,
                "board_type_stats": list(board_type_stats),
                "country_stats": list(country_stats),
                "with_streams": with_streams,
                "with_electives": with_electives,
            }
        )

    @action(detail=True, methods=["get"])
    def schools(self, request, pk=None):
        """Get all schools using this board"""
        school_board = self.get_object()
        schools = School.objects.filter(school_board=school_board).order_by(
            "-created_at"
        )
        page = self.paginate_queryset(schools)
        if page is not None:
            serializer = SchoolSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = SchoolSerializer(schools, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=["get"])
    def board_types(self, request):
        """Get all available board types"""
        choices = SchoolBoard.BOARD_TYPE_CHOICES
        return Response(
            [{"value": choice[0], "label": choice[1]} for choice in choices]
        )

    @action(detail=False, methods=["get"])
    def by_country(self, request):
        """Get school boards grouped by country"""
        boards = (
            SchoolBoard.objects.filter(is_active=True, country__isnull=False)
            .select_related("country")
            .order_by("country__name", "sort_order", "name")
        )

        # Group by country
        grouped = {}
        for board in boards:
            country_code = board.country.code
            if country_code not in grouped:
                grouped[country_code] = {
                    "country": {"code": board.country.code, "name": board.country.name},
                    "boards": [],
                }
            grouped[country_code]["boards"].append(SchoolBoardSerializer(board).data)

        return Response(list(grouped.values()))

    @action(detail=True, methods=["post"])
    def upload_logo(self, request, pk=None):
        """Upload logo for school board"""
        school_board = self.get_object()
        logo = request.FILES.get("logo")

        if not logo:
            return Response(
                {"error": "No logo file provided"}, status=status.HTTP_400_BAD_REQUEST
            )

        # Validate file type
        allowed_types = ["image/jpeg", "image/png", "image/gif", "image/svg+xml"]
        if logo.content_type not in allowed_types:
            return Response(
                {"error": "Invalid file type. Allowed: JPEG, PNG, GIF, SVG"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Validate file size (max 5MB)
        if logo.size > 5 * 1024 * 1024:
            return Response(
                {"error": "File size too large. Max 5MB"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        school_board.logo = logo
        school_board.save()

        return Response(
            {
                "message": "Logo uploaded successfully",
                "logo_url": school_board.logo.url if school_board.logo else None,
            }
        )


class SchoolTypeViewSet(viewsets.ModelViewSet):
    """
    CRUD operations for SchoolType model
    """

    queryset = SchoolType.objects.all().order_by("sort_order", "name")
    serializer_class = SchoolTypeSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["code", "name", "institution_type", "ownership", "gender_type"]
    ordering_fields = [
        "name",
        "code",
        "sort_order",
        "is_active",
        "min_grade",
        "max_grade",
    ]

    def get_queryset(self):
        """Filter school types based on query parameters"""
        queryset = super().get_queryset()

        # Filter by institution type
        institution_type = self.request.query_params.get("institution_type")
        if institution_type:
            queryset = queryset.filter(institution_type=institution_type)

        # Filter by ownership
        ownership = self.request.query_params.get("ownership")
        if ownership:
            queryset = queryset.filter(ownership=ownership)

        # Filter by gender type
        gender_type = self.request.query_params.get("gender_type")
        if gender_type:
            queryset = queryset.filter(gender_type=gender_type)

        # Filter by active status
        active_only = self.request.query_params.get("active_only", "true")
        if active_only.lower() == "true":
            queryset = queryset.filter(is_active=True)

        return queryset

    @action(detail=False, methods=["get"])
    def stats(self, request):
        """Get statistics about school types"""
        total = SchoolType.objects.count()
        active = SchoolType.objects.filter(is_active=True).count()

        # Count by institution type
        institution_stats = (
            SchoolType.objects.values("institution_type")
            .annotate(count=Count("id"))
            .order_by("-count")
        )

        # Count by ownership
        ownership_stats = (
            SchoolType.objects.values("ownership")
            .annotate(count=Count("id"))
            .order_by("-count")
        )

        # Count by gender type
        gender_stats = (
            SchoolType.objects.values("gender_type")
            .annotate(count=Count("id"))
            .order_by("-count")
        )

        return Response(
            {
                "total": total,
                "active": active,
                "institution_stats": list(institution_stats),
                "ownership_stats": list(ownership_stats),
                "gender_stats": list(gender_stats),
            }
        )

    @action(detail=True, methods=["get"])
    def schools(self, request, pk=None):
        """Get all schools of this type"""
        school_type = self.get_object()
        schools = School.objects.filter(school_type=school_type).order_by("-created_at")
        page = self.paginate_queryset(schools)
        if page is not None:
            serializer = SchoolSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = SchoolSerializer(schools, many=True)
        return Response(serializer.data)

    @action(detail=False, methods=["get"])
    def institution_types(self, request):
        """Get all available institution types"""
        choices = SchoolType.INSTITUTION_TYPE_CHOICES
        return Response(
            [{"value": choice[0], "label": choice[1]} for choice in choices]
        )

    @action(detail=False, methods=["get"])
    def ownership_types(self, request):
        """Get all available ownership types"""
        choices = SchoolType.OWNERSHIP_CHOICES
        return Response(
            [{"value": choice[0], "label": choice[1]} for choice in choices]
        )

    @action(detail=False, methods=["get"])
    def gender_types(self, request):
        """Get all available gender types"""
        choices = SchoolType.GENDER_CHOICES
        return Response(
            [{"value": choice[0], "label": choice[1]} for choice in choices]
        )


class SchoolCreateView(APIView):
    """
    Create a new school with database setup
    """

    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        try:
            # Debug: Log incoming data
            logger.info(f"School creation request from user: {request.user.username}")
            logger.debug(f"Request data keys: {list(request.data.keys())}")

            # Create mutable copy of request data
            data = request.data.copy()

            # Parse admin_data from JSON string if it exists
            admin_data = {}
            admin_data_str = data.get("admin_data")

            if admin_data_str:
                if isinstance(admin_data_str, str):
                    try:
                        # Try to parse as JSON
                        admin_data = json.loads(admin_data_str)
                        logger.debug(f"Parsed admin_data from JSON: {admin_data}")
                    except json.JSONDecodeError:
                        logger.warning(
                            f"Failed to parse admin_data as JSON: {admin_data_str}"
                        )
                        # Try alternative parsing
                        try:
                            # Handle case: "{'email': 'test@test.com', ...}"
                            admin_data_str = admin_data_str.replace("'", '"')
                            admin_data = json.loads(admin_data_str)
                        except:
                            admin_data = {}
                elif isinstance(admin_data_str, dict):
                    admin_data = admin_data_str
                else:
                    logger.warning(
                        f"admin_data is unexpected type: {type(admin_data_str)}"
                    )

            # Remove admin_data from school data to avoid serializer issues
            if "admin_data" in data:
                del data["admin_data"]

            # Remove individual admin fields if they exist
            admin_fields = [
                "admin_email",
                "admin_password",
                "admin_confirm_password",
                "admin_first_name",
                "admin_last_name",
                "admin_phone",
            ]
            for field in admin_fields:
                if field in data:
                    del data[field]

            # Clean up any None or empty string values that might cause issues
            for key in list(data.keys()):
                if data[key] in [None, "", "null", "undefined"]:
                    del data[key]

            logger.debug(f"Cleaned data for serializer: {list(data.keys())}")

            # Initialize serializer
            serializer = SchoolSerializer(data=data)

            if not serializer.is_valid():
                logger.error(f"Serializer validation failed: {serializer.errors}")
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

            # Get validated data
            validated_data = serializer.validated_data
            logger.debug(f"Serializer validated successfully")

            # Get slug safely
            school_slug = validated_data.get("slug")
            if not school_slug:
                logger.error("No slug found in validated data")
                return Response(
                    {"error": "School slug is required"},
                    status=status.HTTP_400_BAD_REQUEST,
                )

            if not isinstance(school_slug, str):
                logger.error(f"Slug is not a string: {type(school_slug)}")
                return Response(
                    {"error": "School slug must be a string"},
                    status=status.HTTP_400_BAD_REQUEST,
                )

            # Generate unique database name
            school_id = str(uuid.uuid4())[:8]
            db_name = f"day_scholar_{school_slug}_{school_id}_db".lower().replace(
                "-", "_"
            )
            logger.info(f"Generated database name: {db_name}")

            # Create school instance
            try:
                school = serializer.save(db_name=db_name)
                logger.info(
                    f"School instance created successfully: {school.name} (ID: {school.id})"
                )

                # Try to create database (async in production)
                database_created = False
                try:
                    self._create_database(db_name)
                    database_created = True
                    logger.info(f"Database created successfully: {db_name}")
                except Exception as db_error:
                    logger.warning(
                        f"Database creation failed (but school was created): {str(db_error)}"
                    )
                    # School is already created, continue

                # Try to apply migrations if database was created
                if database_created:
                    try:
                        self._apply_migrations(db_name)
                        logger.info(f"Migrations applied to database: {db_name}")
                    except Exception as migration_error:
                        logger.warning(f"Migration failed: {str(migration_error)}")

                # Create default admin user if admin_data exists
                admin_created = False
                admin_user_info = None
                if admin_data and admin_data.get("email"):
                    try:
                        admin_user_info = self._create_school_admin(school, admin_data)
                        if admin_user_info:
                            admin_created = True
                            logger.info(f"Admin user created for school: {school.name}")
                        else:
                            logger.warning(
                                f"Admin user creation returned None for school: {school.name}"
                            )
                    except Exception as admin_error:
                        logger.error(f"Failed to create admin user: {str(admin_error)}")

                # Log successful creation
                logger.info(
                    f"New school created: {school.name} (ID: {school.id}) "
                    f"with DB: {db_name} by {request.user.username}. "
                    f"Database created: {database_created}, Admin created: {admin_created}"
                )

                # DEBUG: Check what's in databases
                self._debug_databases(school, db_name, admin_data)

                # Return success response
                response_data = {
                    "message": "School created successfully",
                    "school": SchoolSerializer(school).data,
                    "database": {"name": db_name, "created": database_created},
                    "admin": {
                        "created": admin_created,
                        "email": admin_data.get("email", "Not specified"),
                        "details": admin_user_info,
                    },
                }

                return Response(response_data, status=status.HTTP_201_CREATED)

            except Exception as save_error:
                logger.error(f"Error saving school: {str(save_error)}", exc_info=True)
                return Response(
                    {"error": f"Failed to create school: {str(save_error)}"},
                    status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                )

        except Exception as general_error:
            logger.error(
                f"Unexpected error in SchoolCreateView: {str(general_error)}",
                exc_info=True,
            )
            return Response(
                {"error": f"Internal server error: {str(general_error)}"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )

    def _create_database(self, db_name):
        """Create a new PostgreSQL database"""
        try:
            # Connect to default database
            conn = psycopg2.connect(
                dbname="postgres",
                user=settings.DATABASES["default"]["USER"],
                password=settings.DATABASES["default"]["PASSWORD"],
                host=settings.DATABASES["default"]["HOST"],
                port=settings.DATABASES["default"]["PORT"],
            )
            conn.autocommit = True
            cursor = conn.cursor()

            # Check if database exists
            cursor.execute("SELECT 1 FROM pg_database WHERE datname = %s", (db_name,))
            exists = cursor.fetchone()

            if not exists:
                # Create new database
                cursor.execute(
                    sql.SQL("CREATE DATABASE {}").format(sql.Identifier(db_name))
                )
                logger.info(f"Database created: {db_name}")
                success = True
            else:
                logger.warning(f"Database already exists: {db_name}")
                success = False

            cursor.close()
            conn.close()

            return success

        except Exception as e:
            logger.error(f"Database creation error: {str(e)}")
            raise

    def _apply_migrations(self, db_name):
        """Apply migrations to the new database"""
        try:
            # Create a temporary settings with new database
            temp_db_settings = settings.DATABASES["default"].copy()
            temp_db_settings["NAME"] = db_name

            # Connect to new database
            with psycopg2.connect(
                dbname=db_name,
                user=temp_db_settings["USER"],
                password=temp_db_settings["PASSWORD"],
                host=temp_db_settings["HOST"],
                port=temp_db_settings["PORT"],
            ) as conn:
                conn.autocommit = True
                cursor = conn.cursor()

                # Create Django migration table if not exists
                cursor.execute(
                    """
                    CREATE TABLE IF NOT EXISTS django_migrations (
                        id SERIAL PRIMARY KEY,
                        app VARCHAR(255) NOT NULL,
                        name VARCHAR(255) NOT NULL,
                        applied TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
                    )
                """
                )

                # Create essential tables structure
                self._create_essential_tables(cursor)
                cursor.close()

            logger.info(f"Migrations applied to database: {db_name}")
            return True

        except Exception as e:
            logger.error(f"Migration error: {str(e)}")
            raise

    def _create_essential_tables(self, cursor):
        """Create ONLY school-specific tables in school database"""
        # SCHOOL DATABASE should have ONLY school-specific tables
        # DO NOT create user/auth tables here - those are in MASTER DB

        tables_sql = [
            # Languages available for this school (synced from master catalog)
            """
            CREATE TABLE IF NOT EXISTS school_admin_schoollanguage (
                id SERIAL PRIMARY KEY,
                code VARCHAR(10) UNIQUE NOT NULL,
                name VARCHAR(100) NOT NULL,
                native_name VARCHAR(100),
                is_default BOOLEAN DEFAULT FALSE,
                is_enabled BOOLEAN DEFAULT FALSE,
                "order" INTEGER DEFAULT 0,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
            )
            """,
            # Academic tables based on your models
            # Standard table
            """
            CREATE TABLE IF NOT EXISTS academics_standard (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) UNIQUE NOT NULL,
                code VARCHAR(20) UNIQUE NOT NULL,
                "order" INTEGER NOT NULL CHECK ("order" >= 1),
                standard_type VARCHAR(20) NOT NULL,
                description TEXT,
                min_age INTEGER,
                max_age INTEGER,
                is_active BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
            )
            """,
            # Section table
            """
            CREATE TABLE IF NOT EXISTS academics_section (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) NOT NULL,
                code VARCHAR(10) UNIQUE NOT NULL,
                description TEXT,
                is_active BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
            )
            """,
            # Academic Year table
            """
            CREATE TABLE IF NOT EXISTS academics_academicyear (
                id SERIAL PRIMARY KEY,
                name VARCHAR(20) UNIQUE NOT NULL,
                start_date DATE NOT NULL,
                end_date DATE NOT NULL,
                is_active BOOLEAN DEFAULT FALSE,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
            )
            """,
            # Academic Class table
            """
            CREATE TABLE IF NOT EXISTS academics_academicclass (
                id SERIAL PRIMARY KEY,
                academic_year_id INTEGER REFERENCES academics_academicyear(id),
                standard_id INTEGER REFERENCES academics_standard(id),
                section_id INTEGER REFERENCES academics_section(id),
                class_teacher_id INTEGER,
                assistant_teacher_id INTEGER,
                room_number VARCHAR(20),
                start_date DATE,
                end_date DATE,
                current_strength INTEGER DEFAULT 0,
                max_strength INTEGER DEFAULT 40 CHECK (max_strength >= 1 AND max_strength <= 100),
                is_active BOOLEAN DEFAULT TRUE,
                notes TEXT,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(academic_year_id, standard_id, section_id)
            )
            """,
            # Subject Category table
            """
            CREATE TABLE IF NOT EXISTS academics_subjectcategory (
                id SERIAL PRIMARY KEY,
                name VARCHAR(50) UNIQUE NOT NULL,
                code VARCHAR(20) UNIQUE NOT NULL,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
            )
            """,
            # Subject Group table
            """
            CREATE TABLE IF NOT EXISTS academics_subjectgroup (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) NOT NULL,
                code VARCHAR(20) UNIQUE NOT NULL,
                standard_id INTEGER REFERENCES academics_standard(id),
                is_active BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(standard_id, name)
            )
            """,
            # Subject table
            """
            CREATE TABLE IF NOT EXISTS academics_subject (
                id SERIAL PRIMARY KEY,
                name VARCHAR(100) NOT NULL,
                code VARCHAR(20) NOT NULL,
                standard_id INTEGER REFERENCES academics_standard(id),
                category_id INTEGER REFERENCES academics_subjectcategory(id),
                subject_group_id INTEGER REFERENCES academics_subjectgroup(id),
                is_mandatory BOOLEAN DEFAULT FALSE,
                is_active BOOLEAN DEFAULT TRUE,
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(standard_id, code)
            )
            """,
            # Class Subject table
            """
            CREATE TABLE IF NOT EXISTS academics_classsubject (
                id SERIAL PRIMARY KEY,
                academic_class_id INTEGER REFERENCES academics_academicclass(id),
                subject_id INTEGER REFERENCES academics_subject(id),
                created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(academic_class_id, subject_id)
            )
            """,
        ]

        for sql_query in tables_sql:
            try:
                cursor.execute(sql_query)
                logger.debug(f"Created school table: {sql_query[:50]}...")
            except Exception as e:
                logger.error(f"Error creating school table: {str(e)}")
                # Continue with next query

    def _create_school_admin(self, school, admin_data):
        """
        Create default school admin user in MASTER DB
        """
        try:
            email = admin_data.get("email")
            password = admin_data.get("password")
            first_name = admin_data.get("first_name", "")
            last_name = admin_data.get("last_name", "")
            phone = admin_data.get("phone", "")

            if not email or not password:
                logger.warning(
                    "School admin creation skipped: email or password missing"
                )
                return None

            with transaction.atomic():
                # 1️⃣ Create or get user (MASTER DB)
                user, created = User.objects.get_or_create(
                    username=email,
                    defaults={
                        "email": email,
                        "first_name": first_name,
                        "last_name": last_name,
                        "is_staff": True,  # Can access admin features
                        "is_active": True,
                    },
                )

                if created:
                    user.set_password(password)
                    user.save()
                    logger.info(f"School admin user created in MASTER DB: {email}")
                else:
                    logger.warning(
                        f"User already exists in MASTER DB, linking to school: {email}"
                    )

                # 2️⃣ Assign School Admin role via profile (MASTER DB)
                profile, _ = UserProfile.objects.get_or_create(
                    user=user,
                    defaults={
                        "school": school,
                        "phone": phone,
                        "is_primary_contact": True,
                    },
                )

                # If user existed but profile missing
                if profile.school is None:
                    profile.school = school
                    profile.phone = phone
                    profile.is_primary_contact = True
                    profile.save()

                # 3️⃣ Assign Django Group (permissions) - MASTER DB
                try:
                    school_admin_group = Group.objects.get(name="School Admin")
                    user.groups.add(school_admin_group)
                except Group.DoesNotExist:
                    logger.warning(
                        "School Admin group not found. Permissions not assigned."
                    )

                return {
                    "id": user.id,
                    "username": user.username,
                    "email": user.email,
                    "first_name": user.first_name,
                    "last_name": user.last_name,
                    "is_staff": user.is_staff,
                    "is_active": user.is_active,
                    "created": created,
                    "profile_id": profile.id,
                    "school_id": profile.school_id,
                }

        except Exception as e:
            logger.exception(f"Error creating school admin in MASTER DB: {str(e)}")
            return None

    def _debug_databases(self, school, db_name, admin_data):
        """Debug function to check what's in both databases"""
        try:
            logger.info("=" * 80)
            logger.info("DEBUG: Checking database contents")
            logger.info("=" * 80)

            # 1. Check MASTER DB for users
            logger.info("📊 MASTER DATABASE (default) contents:")

            # Check auth_user table
            total_users = User.objects.count()
            logger.info(f"  - auth_user table: {total_users} total users")

            if admin_data.get("email"):
                try:
                    user = User.objects.get(email=admin_data["email"])
                    logger.info(f"  - Found admin user: {user.id}, {user.email}")
                    logger.info(
                        f"    - is_staff: {user.is_staff}, is_active: {user.is_active}"
                    )

                    # Check UserProfile
                    try:
                        profile = UserProfile.objects.get(user=user, school=school)
                        logger.info(
                            f"  - Found UserProfile: ID={profile.id}, School={profile.school_id}"
                        )
                    except UserProfile.DoesNotExist:
                        logger.error(
                            f"  ❌ UserProfile NOT FOUND for user {user.id} and school {school.id}"
                        )
                except User.DoesNotExist:
                    logger.error(
                        f"  ❌ Admin user {admin_data['email']} NOT FOUND in MASTER DB"
                    )

            # Check School table
            total_schools = School.objects.count()
            logger.info(f"  - schools_school table: {total_schools} total schools")
            logger.info(
                f"  - New school: ID={school.id}, Name='{school.name}', DB='{school.db_name}'"
            )

            # 2. Check SCHOOL DB for tables
            logger.info(f"📊 SCHOOL DATABASE ('{db_name}') contents:")
            try:
                conn = psycopg2.connect(
                    dbname=db_name,
                    user=settings.DATABASES["default"]["USER"],
                    password=settings.DATABASES["default"]["PASSWORD"],
                    host=settings.DATABASES["default"]["HOST"],
                    port=settings.DATABASES["default"]["PORT"],
                )
                cursor = conn.cursor()

                # List all tables
                cursor.execute(
                    """
                    SELECT table_name 
                    FROM information_schema.tables 
                    WHERE table_schema = 'public'
                    ORDER BY table_name
                """
                )
                tables = cursor.fetchall()

                if tables:
                    logger.info(f"  - Found {len(tables)} tables:")
                    for table in tables:
                        table_name = table[0]
                        # Check row count
                        cursor.execute(f"SELECT COUNT(*) FROM {table_name}")
                        count = cursor.fetchone()[0]
                        logger.info(f"    - {table_name}: {count} rows")

                        # Show first few rows for key tables
                        if count > 0 and table_name in [
                            "academics_standard",
                            "academics_section",
                        ]:
                            cursor.execute(f"SELECT id, name FROM {table_name} LIMIT 5")
                            rows = cursor.fetchall()
                            logger.info(f"      Sample: {rows}")
                else:
                    logger.warning("  ⚠️  No tables found in school database!")

                cursor.close()
                conn.close()

            except Exception as db_error:
                logger.error(f"  ❌ Could not connect to school DB: {str(db_error)}")

            logger.info("=" * 80)

        except Exception as e:
            logger.error(f"Debug function failed: {str(e)}")


class SchoolDetailView(APIView):
    """
    Get school details by ID
    """

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, pk):
        try:
            school = School.objects.get(pk=pk)
            serializer = SchoolSerializer(school)
            return Response(serializer.data)
        except School.DoesNotExist:
            return Response(
                {"error": "School not found"}, status=status.HTTP_404_NOT_FOUND
            )
