"""Square payment integration via Square API."""

import time
import uuid
from typing import Dict, Any, Optional

import httpx

from agenticlypay.config import config


class SquareClientManager:
    """Manages Square payouts via Square Connect API."""

    def __init__(self):
        """Initialize the Square client."""
        self.application_id = config.square_application_id
        self.access_token = config.square_access_token
        self.location_id = config.square_location_id
        self.environment = config.square_environment or "production"
        self.api_base_url = (
            "https://connect.squareup.com/v2"
            if self.environment == "production"
            else "https://connect.squareupsandbox.com/v2"
        )

    def _get_headers(self) -> Dict[str, str]:
        """Return headers for Square API requests."""
        if not self.access_token:
            raise ValueError("Square access token not configured")

        return {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json",
            "Square-Version": "2024-02-22",
        }

    def send_payout(
        self,
        email: str,
        amount: int,
        currency: str = "USD",
        reference: Optional[str] = None,
    ) -> Dict[str, Any]:
        """
        Send a payout via Square.

        Args:
            email: Recipient email (mapped to recipient_id metadata)
            amount: Amount in cents
            currency: ISO currency code
            reference: Optional reference string

        Returns:
            Dictionary with payout status details
        """
        if not self.location_id:
            raise ValueError("Square location ID not configured")

        headers = self._get_headers()
        idempotency_key = str(uuid.uuid4())

        # Square payouts typically reference destination IDs (bank accounts).
        # For this implementation, store the developer email in metadata.
        payout_data = {
            "idempotency_key": idempotency_key,
            "location_id": self.location_id,
            "amount_money": {
                "amount": amount,
                "currency": currency.upper(),
            },
            "destination_type": "BANK_ACCOUNT",
            "description": reference or f"Payout for {email}",
            "metadata": {
                "developer_email": email,
            },
        }

        with httpx.Client() as client:
            response = client.post(
                f"{self.api_base_url}/payouts",
                json=payout_data,
                headers=headers,
            )

            if response.status_code not in (200, 201):
                raise Exception(
                    f"Failed to create Square payout: {response.status_code} {response.text}"
                )

            result = response.json()

        payout = result.get("payout", result)
        payout_id = payout.get("id")

        return {
            "success": True,
            "payout_id": payout_id,
            "email": email,
            "amount": amount,
            "currency": currency.upper(),
            "status": payout.get("status", "PENDING"),
            "reference": reference,
            "timestamp": time.time(),
        }

    def get_payout_status(self, payout_id: str) -> Dict[str, Any]:
        """Retrieve payout status from Square."""
        headers = self._get_headers()

        with httpx.Client() as client:
            response = client.get(
                f"{self.api_base_url}/payouts/{payout_id}",
                headers=headers,
            )

            if response.status_code != 200:
                raise Exception(
                    f"Failed to get Square payout status: {response.status_code} {response.text}"
                )

            return response.json()

