import base64
from datetime import datetime

import pytz
import requests
from requests_oauthlib import OAuth2Session

from V2.functions.Applications.main import Application
from V2.functions.Shops.main import Shop
from V2.middlewares.auth import API_Error
from V2.Params import Params

scopes = "https://api.ebay.com/oauth/api_scope https://api.ebay.com/oauth/api_scope/sell.marketing.readonly https://api.ebay.com/oauth/api_scope/sell.marketing https://api.ebay.com/oauth/api_scope/sell.inventory.readonly https://api.ebay.com/oauth/api_scope/sell.inventory https://api.ebay.com/oauth/api_scope/sell.account.readonly https://api.ebay.com/oauth/api_scope/sell.account https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly https://api.ebay.com/oauth/api_scope/sell.fulfillment https://api.ebay.com/oauth/api_scope/sell.analytics.readonly https://api.ebay.com/oauth/api_scope/sell.finances https://api.ebay.com/oauth/api_scope/sell.payment.dispute https://api.ebay.com/oauth/api_scope/commerce.identity.readonly https://api.ebay.com/oauth/api_scope/commerce.notification.subscription https://api.ebay.com/oauth/api_scope/commerce.notification.subscription.readonly"

def authUrl(params:Params):
    enterpriseId = params.currentUser.enterpriseId
    app = Application.get("9"+enterpriseId)
    oauth = OAuth2Session(app.apiKey, redirect_uri="Awear_LLC-AwearLLC-Riverr-pfeyxz", scope=scopes)
    url, state = oauth.authorization_url(url="https://auth.ebay.com/oauth2/authorize",prompt='login', locale='en-US')
    return dict(url=url, state=state)

def authToken(params:Params):
    state,code,expires_in = params.args.get("state"),params.args.get("code"),params.args.get("expires_in")
    enterpriseId = params.currentUser.enterpriseId
    app = Application.get("9"+enterpriseId)
    oauth = OAuth2Session(app.apiKey, redirect_uri="Awear_LLC-AwearLLC-Riverr-pfeyxz")
    usrPass = f"{app.apiKey}:{app.apiSecret}"
    b64Val = base64.b64encode(usrPass.encode()).decode()
    res = requests.post("https://api.ebay.com/identity/v1/oauth2/token",
        data=dict(
            code=code,
            grant_type="authorization_code",
            redirect_uri="Awear_LLC-AwearLLC-Riverr-pfeyxz"
        ),
        headers={
            "Authorization": f"Basic {b64Val}",
            "Content-Type": "application/x-www-form-urlencoded"
        }
    )
    if res.status_code in [201,200]:
        token:dict = res.json()
        accessToken=token.get("access_token")
        expiresAt=datetime.now(tz=pytz.utc).timestamp()+int(token.get("expires_in", 7200))
        refreshToken=token.get("refresh_token")
        tokenType = token.get("token_type")
        oauth.token = token
        from V2.functions.Ebay.Shops import getEbayUser
        shop = getEbayUser(accessToken)
        if shop:
            platformShopId = shop.get("userId")
            name = shop.get("username")
            newShop = Shop(
                name=name,
                platformShopId=platformShopId,
                accessToken=accessToken,
                tokenType=tokenType,
                expiresAt=expiresAt,
                refreshToken=refreshToken,
                appId=app.id,
                enterpriseId=app.enterpriseId,
                platformId=app.platformId,
                platformName=app.platformName,
                timezone=pytz.utc.tzname(dt=None),
                uid=params.currentUser.uid,
                url=None
            )
            newShop.save(marketPlaceId = shop.get('registrationMarketplaceId'))
            return newShop.to_dict()
    raise API_Error("Shop not found.", 404)



    #         {
    #     "access_token": "v^1.1#i^1#p^3#r^1...XzMjRV4xMjg0",
    #     "expires_in": 7200,
    #     "refresh_token": "v^1.1#i^1#p^3#r^1...zYjRV4xMjg0",
    #     "refresh_token_expires_in": 47304000,
    #     "token_type": "User Access Token"
    # }
class EbayClient:
    def __init__(self,app:Application,shop:Shop) -> None:
        self.app = app
        self.shop = shop
        self.headers = {
        "Authorization": f"Bearer {shop.accessToken}"
    }
        if self.shop.expiresAt:
            if self.shop.expiresAt < datetime.now(pytz.utc).timestamp(): self.tokenRefresher()

    def tokenRefresher(self):
        res = requests.post(
            url="https://api.ebay.com/identity/v1/oauth2/token", 
            headers={
                "Content-Type":"application/x-www-form-urlencoded",
                **self.headers
            },
            data={
                "grant_type":"refresh_token",
                "refresh_token": self.shop.refreshToken,
                "scope": scopes
            }
        )
        if res.status_code in [200,201]:
            self.shop.accessToken = res.get("access_token")
            self.shop.tokenType = res.get("token_type")
            self.shop.refreshToken = res.get("refresh_token")
            self.shop.expiresAt = int(res.get("expires_in") + datetime.now(pytz.utc).timestamp())
            self.shop.timezone = pytz.utc.tzname(dt=datetime.now())
            self.shop.update()
            return None
        raise API_Error(res.text, res.status_code)

    def get(self, url:str, params:dict={}):
        return requests.get(url, params=params, headers=self.headers)

    def post(self, url:str, data:dict={}):
        return requests.get(url, json=data, headers=self.headers)


