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

API_VERSION = "1"

def authUrl(params:Params):
    url = f"https://login.squarespace.com/api/1/login/oauth/provider/authorize"
    user = params.currentUser
    hostname = params.hostname
    app = Application.get("10"+user.enterpriseId)
    scope = "website.orders,website.inventory,website.products"
    oauth = OAuth2Session(app.apiKey, redirect_uri=f"https://{hostname}/shops/redirects/squarespace", scope=scope)
    url,state = oauth.authorization_url(url, access_type="offline")
    return dict(
        url=url,
        state=state
    )

def authToken(params: Params):
    url = f"https://login.squarespace.com/api/1/login/oauth/provider/tokens"
    code = params.args.get("code")
    user = params.currentUser
    app = Application.get("10"+user.enterpriseId)
    usrPass = f"{app.apiKey}:{app.apiSecret}"
    b64Val = base64.b64encode(usrPass.encode()).decode()
    res = requests.post(url,data=dict(
        grant_type="authorization_code",
        code=code,
        redirect_uri=f"https://{params.hostname}/shops/redirects/squarespace"
    )
    ,headers={
        "Authorization": f"Basic {b64Val}",
        "Content-Type": "application/x-www-form-urlencoded",
        "User-Agent": "curl/7.54.0"
    })
    # print(res.text)
    if res.status_code in [201,200]:
        data:dict = res.json()
        accessToken,tokenType,refreshToken = data.get("access_token"),data.get("token_type"), data.get("refresh_token")
        from V2.functions.Squarespace.Shops import getSquarespaceShop
        squarespaceShop = getSquarespaceShop(accessToken)
        if squarespaceShop:
            shop = Shop(
                uid=user.uid,
                enterpriseId=user.enterpriseId,
                accessToken=accessToken,
                expiresAt=data.get("access_token_expires_at"),
                apiVersion="1.0",
                appId=app.id,
                name=squarespaceShop.get("title"),
                url=squarespaceShop.get("url"),
                platformShopId=squarespaceShop.get("id"),
                timezone=squarespaceShop.get("timeZone"),
                refreshToken=refreshToken,
                tokenType=tokenType,
                platformId=app.platformId,
                platformName=app.platformName,
            )
            shop.save()
            return shop.to_dict()
    raise API_Error("Shop not found.", 404)
    

class SquarespaceClient:
    def __init__(self,app:Application,shop:Shop) -> None:
        self.app = app
        self.shop = shop
        self.Authorization =f"Basic {base64.b64encode(f'{app.apiKey}:{app.apiSecret}'.encode()).decode()}" 
        self.headers = {"Authorization":f"Bearer {shop.accessToken}"}
        if self.shop.expiresAt:
            if self.shop.expiresAt < datetime.now(pytz.utc).timestamp(): self.refreshToken()
        # else: print(self.shop)

    def refreshToken(self):
        res = requests.post("https://login.squarespace.com/api/1/login/oauth/provider/tokens", 
            json=dict(
                grant_type="refresh_token",
                refresh_token=self.shop.refreshToken
            ), 
            headers={
                "Authorization": self.Authorization,
                "Content-Type": "application/json",
                "User-Agent": "curl/7.54.0"
            }
        )
        if res.status_code in [200,201]:
            res = res.json()
            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("access_token_expires_at"))
            self.shop.timezone = pytz.utc.tzname(dt=datetime.now())
            self.shop.update()
            return None
        else: 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.post(url,json=data, headers={
            "Content-Type": "application/json",
            "User-Agent": "curl/7.54.0",
            **self.headers
        })
    
    def put(self, url:str, data:dict={}):
        return requests.put(url,data=data, headers=self.headers)
    
    def upload(self, url:str, files={}):
        return requests.put(url,files=files, headers=self.headers)
    
    def delete(self, url:str):
        return requests.delete(url, headers=self.headers)

