from rest_framework.views import APIView
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from rest_framework import status
from apps.masterdata.platform_setting import PlatformSetting
from urllib.parse import urlparse


ALLOWED_BOOL_KEYS = {
    "lucky_dip_allow_main_wallet",
    "whatsapp_enabled",
}

ALLOWED_STRING_KEYS = {
    "supercoin_default_monthly_limit",
    "supercoin_default_conversion_percentage",
    "razorpay_active_mode",
    "razorpay_test_key_id",
    "razorpay_test_key_secret",
    "razorpay_live_key_id",
    "razorpay_live_key_secret",
    "razorpay_test_webhook_secret",
    "razorpay_live_webhook_secret",
    "sms_active_gateway",
    "sms_twilio_account_sid",
    "sms_twilio_auth_token",
    "sms_twilio_from_number",
    "sms_msg91_auth_key",
    "sms_msg91_sender_id",
    "sms_msg91_route",
    "sms_textlocal_api_key",
    "sms_textlocal_sender",
    "whatsapp_active_provider",
    "whatsapp_meta_base_url",
    "whatsapp_meta_api_version",
    "whatsapp_meta_phone_number_id",
    "whatsapp_meta_access_token",
    "whatsapp_default_country_code",
    "withdrawal_otp_channel",
    "social_facebook_url",
    "social_instagram_url",
    "social_youtube_url",
    "social_linkedin_url",
    "social_x_url",
    "social_telegram_url",
    "enabled_languages",
}

LANGUAGE_CODES = {
    "en", "hi", "bn", "te", "mr", "ta", "ur", "gu", "kn", "ml", "pa", "or",
    "es", "fr", "de", "ar", "zh-CN", "ru", "ja", "pt",
}

SOCIAL_KEYS = {
    "social_facebook_url",
    "social_instagram_url",
    "social_youtube_url",
    "social_linkedin_url",
    "social_x_url",
    "social_telegram_url",
}


def _looks_like_url(value: str) -> bool:
    parsed = urlparse(value)
    return parsed.scheme in {"http", "https"} and bool(parsed.netloc)


class AdminPlatformSettingsView(APIView):
    permission_classes = [IsAdminUser]

    def get(self, request):
        test_secret = PlatformSetting.get_value("razorpay_test_key_secret", "")
        live_secret = PlatformSetting.get_value("razorpay_live_key_secret", "")
        test_webhook_secret = PlatformSetting.get_value("razorpay_test_webhook_secret", "")
        live_webhook_secret = PlatformSetting.get_value("razorpay_live_webhook_secret", "")
        twilio_auth_token = PlatformSetting.get_value("sms_twilio_auth_token", "")
        msg91_auth_key = PlatformSetting.get_value("sms_msg91_auth_key", "")
        textlocal_api_key = PlatformSetting.get_value("sms_textlocal_api_key", "")
        whatsapp_meta_access_token = PlatformSetting.get_value("whatsapp_meta_access_token", "")

        return Response(
            {
                "lucky_dip_allow_main_wallet": PlatformSetting.get_bool("lucky_dip_allow_main_wallet", True),
                "razorpay_active_mode": PlatformSetting.get_value("razorpay_active_mode", "test") or "test",
                "razorpay_test_key_id": PlatformSetting.get_value("razorpay_test_key_id", ""),
                "razorpay_live_key_id": PlatformSetting.get_value("razorpay_live_key_id", ""),
                "has_razorpay_test_key_secret": bool(test_secret),
                "has_razorpay_live_key_secret": bool(live_secret),
                "has_razorpay_test_webhook_secret": bool(test_webhook_secret),
                "has_razorpay_live_webhook_secret": bool(live_webhook_secret),
                "sms_active_gateway": PlatformSetting.get_value("sms_active_gateway", "twilio") or "twilio",
                "sms_twilio_account_sid": PlatformSetting.get_value("sms_twilio_account_sid", ""),
                "sms_twilio_from_number": PlatformSetting.get_value("sms_twilio_from_number", ""),
                "has_sms_twilio_auth_token": bool(twilio_auth_token),
                "sms_msg91_sender_id": PlatformSetting.get_value("sms_msg91_sender_id", ""),
                "sms_msg91_route": PlatformSetting.get_value("sms_msg91_route", ""),
                "has_sms_msg91_auth_key": bool(msg91_auth_key),
                "sms_textlocal_sender": PlatformSetting.get_value("sms_textlocal_sender", ""),
                "has_sms_textlocal_api_key": bool(textlocal_api_key),
                "whatsapp_enabled": PlatformSetting.get_bool("whatsapp_enabled", False),
                "whatsapp_active_provider": PlatformSetting.get_value("whatsapp_active_provider", "meta_cloud") or "meta_cloud",
                "whatsapp_meta_base_url": PlatformSetting.get_value("whatsapp_meta_base_url", "https://graph.facebook.com") or "https://graph.facebook.com",
                "whatsapp_meta_api_version": PlatformSetting.get_value("whatsapp_meta_api_version", "v20.0") or "v20.0",
                "whatsapp_meta_phone_number_id": PlatformSetting.get_value("whatsapp_meta_phone_number_id", ""),
                "whatsapp_default_country_code": PlatformSetting.get_value("whatsapp_default_country_code", "+91") or "+91",
                "has_whatsapp_meta_access_token": bool(whatsapp_meta_access_token),
                "withdrawal_otp_channel": PlatformSetting.get_value("withdrawal_otp_channel", "sms") or "sms",
                "social_facebook_url": PlatformSetting.get_value("social_facebook_url", "") or "",
                "social_instagram_url": PlatformSetting.get_value("social_instagram_url", "") or "",
                "social_youtube_url": PlatformSetting.get_value("social_youtube_url", "") or "",
                "social_linkedin_url": PlatformSetting.get_value("social_linkedin_url", "") or "",
                "social_x_url": PlatformSetting.get_value("social_x_url", "") or "",
                "social_telegram_url": PlatformSetting.get_value("social_telegram_url", "") or "",
                "enabled_languages": PlatformSetting.get_value(
                    "enabled_languages",
                    "en,hi,bn,te,mr,ta,ur,gu,kn,ml,pa,or"
                ) or "en,hi,bn,te,mr,ta,ur,gu,kn,ml,pa,or",
                "supercoin_default_monthly_limit": PlatformSetting.get_value("supercoin_default_monthly_limit", "0") or "0",
                "supercoin_default_conversion_percentage": PlatformSetting.get_value("supercoin_default_conversion_percentage", "100") or "100",
            }
        )

    def post(self, request):
        key = request.data.get("key")
        value = request.data.get("value")
        if not key:
            return Response({"error": "Missing key."}, status=status.HTTP_400_BAD_REQUEST)

        if key in ALLOWED_BOOL_KEYS:
            bool_value = str(value).lower() in ("1", "true", "yes", "on")
            PlatformSetting.set_bool(key, bool_value)
            return Response({"success": True, "key": key, "value": bool_value})

        if key in ALLOWED_STRING_KEYS:
            normalized = str(value or "").strip()

            if key == "razorpay_active_mode" and normalized not in {"test", "live"}:
                return Response({"error": "razorpay_active_mode must be 'test' or 'live'."}, status=status.HTTP_400_BAD_REQUEST)

            if key == "sms_active_gateway" and normalized not in {"twilio", "msg91", "textlocal"}:
                return Response({"error": "sms_active_gateway must be one of: twilio, msg91, textlocal."}, status=status.HTTP_400_BAD_REQUEST)

            if key == "whatsapp_active_provider" and normalized not in {"meta_cloud"}:
                return Response({"error": "whatsapp_active_provider must be: meta_cloud."}, status=status.HTTP_400_BAD_REQUEST)

            if key == "withdrawal_otp_channel" and normalized not in {"sms", "whatsapp", "email"}:
                return Response({"error": "withdrawal_otp_channel must be one of: sms, whatsapp, email."}, status=status.HTTP_400_BAD_REQUEST)

            if key in SOCIAL_KEYS and normalized and not _looks_like_url(normalized):
                return Response({"error": f"{key} must be a valid http/https URL."}, status=status.HTTP_400_BAD_REQUEST)

            if key in {"supercoin_default_monthly_limit", "supercoin_default_conversion_percentage"}:
                try:
                    num = float(normalized)
                    if num < 0:
                        raise ValueError
                    if key == "supercoin_default_conversion_percentage" and num > 100:
                        return Response({"error": "supercoin_default_conversion_percentage must be between 0 and 100."}, status=status.HTTP_400_BAD_REQUEST)
                except (ValueError, TypeError):
                    return Response({"error": f"{key} must be a non-negative number."}, status=status.HTTP_400_BAD_REQUEST)

            if key == "enabled_languages":
                langs = [segment.strip() for segment in normalized.split(",") if segment.strip()]
                if not langs:
                    return Response({"error": "enabled_languages cannot be empty."}, status=status.HTTP_400_BAD_REQUEST)
                if any(lang not in LANGUAGE_CODES for lang in langs):
                    return Response({"error": "enabled_languages contains unsupported language codes."}, status=status.HTTP_400_BAD_REQUEST)
                normalized = ",".join(langs)

            PlatformSetting.set_value(key, normalized)
            return Response({"success": True, "key": key, "value": normalized})

        return Response({"error": "Unknown or unsupported setting."}, status=status.HTTP_400_BAD_REQUEST)
