from __future__ import unicode_literals
import frappe
import requests
from frappe.model.document import Document


MYGOVID_BASE_URL = "https://api.mygovid.gov.az"
MYGOVID_HEADERS = {
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "az",
    "Content-Type": "application/json",
    "Origin": "https://mygovid.gov.az",
    "Referer": "https://mygovid.gov.az/",
}


class AsanLogin(Document):
    def before_save(self):
        # Если установлен флаг is_default, сбрасываем его у других документов
        if self.is_default:
            existing_defaults = frappe.get_all(
                "Asan Login",
                filters={
                    "is_default": 1,
                    "name": ["!=", self.name]
                }
            )
            
            for default in existing_defaults:
                doc = frappe.get_doc("Asan Login", default.name)
                doc.is_default = 0
                doc.flags.ignore_permissions = True
                doc.save()
                
    def validate(self):
        # Проверяем обязательные поля
        if not self.phone:
            frappe.throw("Phone is required")

        if not self.user_id:
            frappe.throw("User ID is required")


@frappe.whitelist()
def start_mygovid_login(asan_login_name):
    """
    Start MyGovID ASAN Sign login.
    This is a long-polling request that waits for user confirmation in ASAN Sign app.
    Returns JWT token after user confirms.
    """
    doc = frappe.get_doc("Asan Login", asan_login_name)

    if not doc.user_id or not doc.phone:
        return {"success": False, "message": "User ID and phone number are required"}

    url = f"{MYGOVID_BASE_URL}/ssoauth/api/v1/logIn/asanSignLogin"

    payload = {
        "mobileKey": None,
        "phoneNumber": doc.phone,
        "userId": doc.user_id,
        "recaptcha3Response": "",
    }

    try:
        # Long timeout - waits for user to confirm in ASAN Sign app
        response = requests.post(
            url, json=payload, headers=MYGOVID_HEADERS, timeout=120
        )

        if response.status_code in [200, 201]:
            data = response.json()
            token = data.get("data", {}).get("token")

            # Save token to document
            if token:
                doc.mygovid_token = token
                doc.save(ignore_permissions=True)
                frappe.db.commit()

            return {
                "success": True,
                "token": token,
                "transaction": data.get("transaction"),
            }
        else:
            return {
                "success": False,
                "message": f"API error: status {response.status_code}",
                "response_data": response.text,
            }
    except requests.exceptions.Timeout:
        return {
            "success": False,
            "message": "Request timed out. User did not confirm in ASAN Sign app.",
        }
    except requests.exceptions.RequestException as e:
        frappe.log_error(f"MyGovID API error: {str(e)}", "MyGovID API Error")
        return {"success": False, "message": f"Network error: {str(e)}"}
    except Exception as e:
        frappe.log_error(
            f"MyGovID unexpected error: {str(e)}\n{frappe.get_traceback()}",
            "MyGovID API Error",
        )
        return {"success": False, "message": f"Error: {str(e)}"}


@frappe.whitelist()
def get_mygovid_verification_code(asan_login_name):
    """
    Get verification code for MyGovID ASAN Sign.
    Call this immediately after starting login to get the 4-digit code
    that user needs to confirm in ASAN Sign app.
    """
    doc = frappe.get_doc("Asan Login", asan_login_name)

    if not doc.user_id:
        return {"success": False, "message": "User ID is required"}

    url = f"{MYGOVID_BASE_URL}/ssoauth/api/v1/logIn/asanSignLogin/verificationCode/{doc.user_id}"

    try:
        response = requests.get(url, headers=MYGOVID_HEADERS, timeout=30)

        if response.status_code in [200, 201]:
            data = response.json()
            return {
                "success": True,
                "code": data.get("data", {}).get("code"),
                "transaction": data.get("transaction"),
            }
        else:
            return {
                "success": False,
                "message": f"API error: status {response.status_code}",
                "response_data": response.text,
            }
    except requests.exceptions.RequestException as e:
        frappe.log_error(f"MyGovID API error: {str(e)}", "MyGovID API Error")
        return {"success": False, "message": f"Network error: {str(e)}"}
    except Exception as e:
        frappe.log_error(
            f"MyGovID unexpected error: {str(e)}\n{frappe.get_traceback()}",
            "MyGovID API Error",
        )
        return {"success": False, "message": f"Error: {str(e)}"}