from dataclasses import dataclass
from datetime import datetime

import pytz
import requests

from configs.firebase import ArrayUnion, DocumentSnapshot, db
from V2.functions.main import DocumentData
from V2.middlewares.auth import API_Error
from V2.Params import Params

projectId="prj_dic3lcCCpMEV2JXsZJy3JIyKXi0D"

api_token = "XR7pJeG12SlLSMYGW2SRHvUN"


def addCustomDomain(params:Params):
    domains = params.args.get("domains")
    primaryDomain = params.args.get("primaryDomain")
    shopId = params.id
    query = db.collection("enterprises").where("hostnames", "array_contains_any", domains).get()
    if query: raise API_Error("Domain already exists", 400)
    url = f"https://api.vercel.com/v1/projects/{projectId}/domains"
    headers = {
        "Authorization": f"Bearer {api_token}",
        "Content-Type": "application/json"
    }
    for domain in domains:
        payload = {
            "name": domain,
            "redirect": primaryDomain
            }
        try:
            response = requests.post(url, headers=headers, json=payload)
            response.raise_for_status()  # Raise an error for HTTP status codes >= 400
            if response.status_code in [200, 201]:
                data = response.json()
                if not data.get("verified"): db.collection("shops").document(shopId).update({
                        "domains": ArrayUnion([primaryDomain]+[domain]),
                        "domain": primaryDomain,
                    })
                else: db.collection("shops").document(shopId).update({
                        "pendingDomains": ArrayUnion([domain])
                    })
                return response.json()
        except requests.exceptions.RequestException as e:
            print(e)
            return None

@dataclass(kw_only=True)
class Shop(DocumentData):
    name:str
    platformId:str
    platformName:str
    platformShopId:str
    appId:str
    url:str|None
    accessToken:str|None
    refreshToken:str|None = None
    apiVersion:str|None = None
    expiresAt:int|None = None
    tokenType:str|None = None
    consumerKey:str|None = None
    consumerSecret:str|None = None
    apiKey:str|None = None
    apiSecret:str|None = None
    timezone:str|None = pytz.utc.tzname(dt=datetime.now(pytz.utc))
    disabled:bool|None = False
    shipstationConnection:dict|None = None

    @classmethod
    def get(cls, id:str, credentials=True):
        ref = db.document(f"shopsCredentials/{id}" if credentials else f"shops/{id}").get()
        if ref.exists:return cls.from_dict(ref.to_dict())
        else:
            ref = db.document(f"shops/{id}").get()
            return cls.from_dict(ref.to_dict())

    @classmethod
    def getUserShops(cls, uid:str): return getUserShops(uid)
    
    def save(self, **kwargs):
        shop = getShopByPlatformId(self.uid, self.platformId, self.platformShopId)
        self.updatedAt = datetime.now()
        if shop:
            ref = db.document(f"shops/{shop.id}")
            self.id = shop.id
            ref.set(self.to_dict(), merge=True)
        else:
            _,ref = db.collection('shops').add(self.to_dict())
            ref.update({ "id": ref.id })
            self.id = ref.id
        db.document(f"shopsCredentials/{self.id}").set(dict(**self.to_dict(), **kwargs),merge=True)
        return self
    
    def update(self, **kwargs):
        db.document(f"shops/{self.id}").update(dict(**self.to_dict(), **kwargs))
        db.document(f"shopsCredentials/{self.id}").update(dict(**self.to_dict(), **kwargs))


def getShopByPlatformId(uid:str, platformId:str, platformShopId:str):
    ref:list[DocumentSnapshot] = db.collection("shopsCredentials").where("platformShopId", "==", platformShopId).where("platformId", "==", platformId).where("uid", "==", uid).get()
    if ref: return Shop.from_dict(ref[0].to_dict())

def getShopsByPlatformId(platformId: str = None, credentials=False):
    docs = db.collection("shopsCredentials" if credentials else "shops").where("platformId", "==", platformId).get()
    return [Shop.from_dict(doc.to_dict()) for doc in docs]

def getPopupStore(domain: str = None):
    docs = db.collection("shops").where("domain", "==", domain).get()
    if docs: return [Shop.from_dict(doc.to_dict()) for doc in docs][0]
    return None

def getUserShops(uid:str):
    docs = db.collection("shopsCredentials").where("uid", "==", uid).get()
    return [Shop.from_dict(doc.to_dict()) for doc in docs]

def disableShop(shopId):
    ref = db.document(f"shopsCredentials/{shopId}").get()
    if ref.exists: ref.reference.update(dict(
            disabled=True
        ))