import requests
import logging
from django.core.cache import cache
from common.env import env

logger = logging.getLogger(__name__)

class SendService:
    GET = "GET"
    POST = "POST"
    PATCH = "PATCH"
    CONTACT = "contact"
    CACHE_KEY = "eskiz_token"
    TOKEN_LIFETIME = 86400 * 20  # Eskiz tokens usually last 30 days, we cache for 20

    def __init__(
        self, api_url=None, email=None, password=None, callback_url=None
    ):
        self.api_url = (api_url or env("SMS_API_URL")).rstrip("/")
        self.email = email or env("SMS_LOGIN")
        self.password = password or env("SMS_PASSWORD")
        self.callback_url = callback_url
        self.headers = {
            "Accept": "application/json",
        }

        self.methods = {
            "auth_user": "auth/user",
            "auth_login": "auth/login",
            "auth_refresh": "auth/refresh",
            "send_message": "message/sms/send",
        }

    def request(self, api_path, data=None, method=None, headers=None):
        url = f"{self.api_url}/{api_path}"
        method = method or self.POST
        final_headers = self.headers.copy()
        if headers:
            final_headers.update(headers)

        try:
            # Reverting to data=data (form-encoded) as it was working before
            response = requests.request(
                method,
                url,
                data=data if method != self.GET else None,
                params=data if method == self.GET else None,
                headers=final_headers,
                timeout=10
            )
            response.raise_for_status()
            return response.json()
        except requests.exceptions.HTTPError as e:
            logger.error(f"SMS API HTTP Error: {e.response.status_code} - {e.response.text}")
            return e.response.json()
        except Exception as e:
            logger.error(f"SMS API Request Exception: {str(e)}")
            return {"status": "error", "message": str(e)}

    def get_token(self):
        token = cache.get(self.CACHE_KEY)
        if not token:
            logger.info("Eskiz token not found in cache, authenticating...")
            auth_res = self.auth()
            if auth_res.get("status") == "success" or "data" in auth_res:
                token = auth_res.get("data", {}).get("token")
                if token:
                    cache.set(self.CACHE_KEY, token, self.TOKEN_LIFETIME)
            else:
                logger.error(f"Eskiz Auth Failed: {auth_res}")
        return token

    def auth(self):
        data = {"email": self.email, "password": self.password}
        # Eskiz login expects JSON
        return self.request(
            self.methods["auth_login"], data=data, method=self.POST
        )

    def refresh_token(self):
        token = self.get_token()
        headers = {"Authorization": f"Bearer {token}"}

        res = self.request(
            self.methods["auth_refresh"],
            method=self.PATCH,
            headers=headers,
        )
        if res.get("status") == "success":
            # Some Eskiz versions return a new token on refresh
            new_token = res.get("data", {}).get("token")
            if new_token:
                cache.set(self.CACHE_KEY, new_token, self.TOKEN_LIFETIME)
        return res

    def get_my_user_info(self):
        token = self.get_token()
        headers = {"Authorization": f"Bearer {token}"}

        return self.request(
            self.methods["auth_user"], method=self.GET, headers=headers
        )

    def add_sms_contact(self, first_name, phone_number, group):
        token = self.get_token()
        headers = {"Authorization": f"Bearer {token}"}

        data = {
            "name": first_name,
            "email": self.email,
            "group": group,
            "mobile_phone": phone_number,
        }

        return self.request(
            self.CONTACT,
            data=data,
            method=self.POST,
            headers=headers,
        )

    def send_sms(self, phone_number, message):
        token = self.get_token()
        if not token:
            return {"status": "error", "message": "Failed to obtain auth token"}

        headers = {"Authorization": f"Bearer {token}"}

        # Use integer 4546 for sender name
        data = {
            "from": 4546,
            "mobile_phone": phone_number,
            "callback_url": self.callback_url,
            "message": message,
        }

        res = self.request(
            self.methods["send_message"],
            data=data,
            method=self.POST,
            headers=headers,
        )
        return res