# ==============================#
# LANGUAGE / TRANSLATION VIEWS  #
# ==============================#
import logging
import requests

from django.conf import settings
from django.db import connections
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import permissions, status

from .models import Language

logger = logging.getLogger(__name__)

GOOGLE_TRANSLATE_URL = "https://translation.googleapis.com/language/translate/v2"

# Table lives in each school's own database (school_admin.SchoolLanguage)
SCHOOL_LANGUAGE_TABLE_SQL = """
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
)
"""


def _get_user_school(request):
    """Resolve the school for the current user from their master-DB profile."""
    school = getattr(request, "school", None)
    if school:
        return school
    profile = getattr(request.user, "profile", None) or getattr(
        request.user, "userprofile", None
    )
    return profile.school if profile else None


def ensure_school_language_table(alias="school"):
    """Create the languages table in the school DB if it doesn't exist yet."""
    with connections[alias].cursor() as cursor:
        cursor.execute(SCHOOL_LANGUAGE_TABLE_SQL)


def sync_school_languages(alias="school"):
    """
    Ensure the school DB has a row for every active language in the master
    catalog. Existing rows keep their is_enabled state; the default language
    (English) is forced enabled. Returns the up-to-date queryset.
    """
    from school_admin.models import SchoolLanguage

    ensure_school_language_table(alias)

    catalog = Language.objects.using("default").filter(is_active=True)
    existing = {l.code: l for l in SchoolLanguage.objects.using(alias).all()}

    for lang in catalog:
        row = existing.get(lang.code)
        if row is None:
            SchoolLanguage.objects.using(alias).create(
                code=lang.code,
                name=lang.name,
                native_name=lang.native_name,
                is_default=lang.is_default,
                is_enabled=lang.is_default,  # default language starts enabled
                order=lang.order,
            )
        else:
            changed = False
            for field in ("name", "native_name", "is_default", "order"):
                if getattr(row, field) != getattr(lang, field):
                    setattr(row, field, getattr(lang, field))
                    changed = True
            if row.is_default and not row.is_enabled:
                row.is_enabled = True
                changed = True
            if changed:
                row.save(using=alias)

    active_codes = set(catalog.values_list("code", flat=True))
    return (
        SchoolLanguage.objects.using(alias)
        .filter(code__in=active_codes)
        .order_by("order", "name")
    )


def _languages_payload(rows):
    return [
        {
            "id": row.id,
            "code": row.code,
            "name": row.name,
            "native_name": row.native_name,
            "order": row.order,
            "is_default": row.is_default,
            "is_enabled": row.is_default or row.is_enabled,
        }
        for row in rows
    ]


class SchoolAdminLanguagesView(APIView):
    """
    School admin panel — manage the languages this school offers.
    Data lives in the school's own database.

    GET:  All languages with is_enabled state for the admin's school.
    POST: { language_codes: ['ta', 'te', ...] } — enable exactly these
          (default language, e.g. English, stays always enabled).
    """

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        if not _get_user_school(request):
            return Response(
                {"error": "No school associated with this user"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        rows = sync_school_languages()
        return Response(_languages_payload(rows))

    def post(self, request):
        school = _get_user_school(request)
        if not school:
            return Response(
                {"error": "No school associated with this user"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        enabled_codes = request.data.get("language_codes", [])
        if not isinstance(enabled_codes, list):
            return Response(
                {"error": "language_codes must be a list of language codes"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        rows = sync_school_languages()
        for row in rows:
            if row.is_default:
                continue
            should_enable = row.code in enabled_codes
            if row.is_enabled != should_enable:
                row.is_enabled = should_enable
                row.save(using="school")

        logger.info(
            f"Languages updated for {school.name} "
            f"by {request.user.username}: {enabled_codes}"
        )
        return Response(
            {
                "message": "Language access updated successfully",
                "languages": _languages_payload(
                    rows.model.objects.using("school")
                    .filter(id__in=[r.id for r in rows])
                    .order_by("order", "name")
                ),
            }
        )


class MySchoolLanguagesView(APIView):
    """
    Mobile app (parent/teacher) — languages enabled for the user's school.
    Returns only enabled languages so the app can show its language picker.
    """

    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        if not _get_user_school(request):
            return Response(
                {"error": "No school associated with this user"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        rows = sync_school_languages()
        enabled = [
            lang for lang in _languages_payload(rows) if lang["is_enabled"]
        ]
        return Response({"languages": enabled})


class TranslateView(APIView):
    """
    Proxy to Google Translate v2 so clients don't need to embed the API key.

    POST: { texts: ["Hello", ...], target: "ta", source: "en" (optional) }
    Returns: { translations: ["வணக்கம்", ...] }
    """

    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        from master_admin.credentials import get_credential

        api_key = get_credential("GOOGLE_TRANSLATE_API_KEY")
        if not api_key:
            return Response(
                {"error": "Translation service is not configured"},
                status=status.HTTP_503_SERVICE_UNAVAILABLE,
            )

        texts = request.data.get("texts")
        target = request.data.get("target")
        source = request.data.get("source", "en")

        if not texts or not target:
            return Response(
                {"error": "Both 'texts' (list) and 'target' are required"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        if isinstance(texts, str):
            texts = [texts]
        if len(texts) > 128:
            return Response(
                {"error": "A maximum of 128 texts can be translated per request"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        try:
            resp = requests.post(
                GOOGLE_TRANSLATE_URL,
                params={"key": api_key},
                json={
                    "q": texts,
                    "target": target,
                    "source": source,
                    "format": "text",
                },
                timeout=15,
            )
            resp.raise_for_status()
            data = resp.json()
            translations = [
                t["translatedText"]
                for t in data.get("data", {}).get("translations", [])
            ]
            return Response({"translations": translations})
        except requests.RequestException as e:
            logger.error(f"Google Translate request failed: {e}")
            return Response(
                {"error": "Translation request failed"},
                status=status.HTTP_502_BAD_GATEWAY,
            )
