import requests
import base64
import json
import logging

logger = logging.getLogger(__name__)


class WordPressConnector:
    """Connect to WordPress via the REST API using Application Passwords."""

    def __init__(self, url, username, app_password):
        self.base_url = url.rstrip("/")
        self.api_url = f"{self.base_url}/wp-json/wp/v2"
        self.username = username
        self.app_password = app_password

        # Create auth header
        credentials = f"{username}:{app_password}"
        token = base64.b64encode(credentials.encode()).decode("utf-8")
        self.headers = {
            "Authorization": f"Basic {token}",
            "Content-Type": "application/json",
        }

    # ------------------------------------------------------------------
    def test_connection(self):
        """Test if we can connect to WordPress."""
        try:
            resp = requests.get(
                f"{self.api_url}/users/me",
                headers=self.headers,
                timeout=15,
            )
            return resp.status_code == 200
        except Exception as e:
            logger.error(f"WordPress connection test failed: {e}")
            return False

    # ------------------------------------------------------------------
    def get_categories(self):
        """Get all categories."""
        try:
            resp = requests.get(
                f"{self.api_url}/categories",
                headers=self.headers,
                params={"per_page": 100},
                timeout=15,
            )
            resp.raise_for_status()
            return resp.json()
        except Exception as e:
            logger.error(f"Failed to get categories: {e}")
            return []

    # ------------------------------------------------------------------
    def create_category(self, name, slug=None):
        """Create a new category."""
        try:
            payload = {"name": name}
            if slug:
                payload["slug"] = slug
            resp = requests.post(
                f"{self.api_url}/categories",
                headers=self.headers,
                json=payload,
                timeout=15,
            )
            resp.raise_for_status()
            return resp.json()
        except Exception as e:
            logger.error(f"Failed to create category '{name}': {e}")
            return None

    # ------------------------------------------------------------------
    def get_or_create_category(self, name):
        """Get category ID by name, or create it if it doesn't exist."""
        cats = self.get_categories()
        for cat in cats:
            if cat.get("name", "").lower() == name.lower():
                return cat["id"]
        # Create new
        new_cat = self.create_category(name)
        if new_cat:
            return new_cat.get("id")
        return None

    # ------------------------------------------------------------------
    def get_tags(self):
        """Get all tags."""
        try:
            resp = requests.get(
                f"{self.api_url}/tags",
                headers=self.headers,
                params={"per_page": 100},
                timeout=15,
            )
            resp.raise_for_status()
            return resp.json()
        except Exception as e:
            logger.error(f"Failed to get tags: {e}")
            return []

    # ------------------------------------------------------------------
    def create_tag(self, name, slug=None):
        """Create a new tag."""
        try:
            payload = {"name": name}
            if slug:
                payload["slug"] = slug
            resp = requests.post(
                f"{self.api_url}/tags",
                headers=self.headers,
                json=payload,
                timeout=15,
            )
            resp.raise_for_status()
            return resp.json()
        except Exception as e:
            logger.error(f"Failed to create tag '{name}': {e}")
            return None

    # ------------------------------------------------------------------
    def get_or_create_tag(self, name):
        """Get tag ID by name, or create it if it doesn't exist."""
        tags = self.get_tags()
        for tag in tags:
            if tag.get("name", "").lower() == name.lower():
                return tag["id"]
        new_tag = self.create_tag(name)
        if new_tag:
            return new_tag.get("id")
        return None

    # ------------------------------------------------------------------
    def publish_post(
        self,
        title,
        content_html,
        status="draft",
        categories=None,
        tags=None,
        meta_description="",
        focus_keyword="",
        slug="",
        featured_image_url=None,
    ):
        """Publish or draft a post on WordPress."""
        try:
            payload = {
                "title": title,
                "content": content_html,
                "status": status,
                "categories": categories or [],
                "tags": tags or [],
            }
            if slug:
                payload["slug"] = slug

            # Yoast SEO meta fields (if Yoast is installed)
            if meta_description or focus_keyword:
                payload["meta"] = {}
                if meta_description:
                    payload["meta"]["_yoast_wpseo_metadesc"] = meta_description
                if focus_keyword:
                    payload["meta"]["_yoast_wpseo_focuskw"] = focus_keyword

            # Upload featured image if provided
            if featured_image_url:
                media_id = self.upload_media(featured_image_url)
                if media_id:
                    payload["featured_media"] = media_id

            resp = requests.post(
                f"{self.api_url}/posts",
                headers=self.headers,
                json=payload,
                timeout=30,
            )
            resp.raise_for_status()
            result = resp.json()
            return {
                "id": result.get("id"),
                "link": result.get("link"),
                "status": result.get("status"),
                "title": result.get("title", {}).get("rendered", ""),
            }
        except Exception as e:
            logger.error(f"Failed to publish post: {e}")
            raise Exception(f"WordPress publish failed: {e}")

    # ------------------------------------------------------------------
    def upload_media(self, image_url, filename=None):
        """Download an image from URL and upload it to WordPress media library."""
        try:
            img_resp = requests.get(image_url, timeout=30)
            img_resp.raise_for_status()

            if not filename:
                filename = image_url.split("/")[-1].split("?")[0] or "featured.jpg"

            content_type = img_resp.headers.get("Content-Type", "image/jpeg")
            upload_headers = {
                "Authorization": self.headers["Authorization"],
                "Content-Type": content_type,
                "Content-Disposition": f'attachment; filename="{filename}"',
            }
            resp = requests.post(
                f"{self.api_url}/media",
                headers=upload_headers,
                data=img_resp.content,
                timeout=30,
            )
            resp.raise_for_status()
            return resp.json().get("id")
        except Exception as e:
            logger.error(f"Failed to upload media: {e}")
            return None
