# -*- coding: utf-8 -*-
import urllib.request
import urllib.error
import urllib.parse
import json
import uuid
import platform
import getpass
from datetime import datetime, timezone

class SupabaseGuard:
    SUPABASE_URL = "https://mbfzmvlivyuajmxrecne.supabase.co"
    SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Im1iZnptdmxpdnl1YWpteHJlY25lIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjU0NzgwODQsImV4cCI6MjA4MTA1NDA4NH0.sZltNY30ww2Hb_oopiVDcvXnZRehWRvK2jZZU5MO64s"
    TABLE_NAME = "licenses"
    
    # KONTAK ADMIN
    ADMIN_NAME = "Ardi Abu Ridho"
    ADMIN_WA   = "+62 822-5476-0769"
    VERSION    = "3.1.0"
    
    @staticmethod
    def get_machine_id():
        try:
            node = uuid.getnode()
            return hex(node)[2:]
        except:
            return "UNKNOWN_DEVICE"

    @staticmethod
    def make_request(url, method="GET", data=None):
        headers = {
            "apikey": SupabaseGuard.SUPABASE_KEY,
            "Authorization": "Bearer {}".format(SupabaseGuard.SUPABASE_KEY),
            "Content-Type": "application/json",
            "Prefer": "return=representation"
        }
        req_data = json.dumps(data).encode('utf-8') if data else None
        req = urllib.request.Request(url, data=req_data, headers=headers, method=method)
        try:
            with urllib.request.urlopen(req) as response:
                if response.status in [200, 201, 204]:
                    resp_body = response.read().decode('utf-8')
                    return json.loads(resp_body) if resp_body else []
                return None
        except:
            return None

    @staticmethod
    def format_status_box(status, expiry, days_left, app_name, tier, machine_id=None):
        border = "=" * 60
        nl = "\n"
        
        expiry_text = "Seumur Hidup"
        if expiry:
            expiry_text = "{} (Sisa {} hari)".format(expiry, days_left)
            
        lines = []
        lines.append(nl + border)
        lines.append(" STATUS LISENSI (AHZA TOOLS)")
        lines.append(border)
        lines.append(" Aplikasi     : {}".format(app_name))
        lines.append(" Versi        : {}".format(SupabaseGuard.VERSION))
        lines.append(" Status       : {}".format(status.upper()))
        lines.append(" Tipe Paket   : {}".format(tier.upper()))
        lines.append(" Masa Aktif   : {}".format(expiry_text))
        
        if machine_id:
            lines.append(" Machine ID   : {}".format(machine_id))
        lines.append("")
        lines.append(" Hubungi Admin jika ada kendala:")
        lines.append(" {} ({})".format(SupabaseGuard.ADMIN_NAME, SupabaseGuard.ADMIN_WA))
        lines.append(border + nl)
        
        return nl.join(lines)

    @staticmethod
    def check_license(app_name="BIG Downloader QGIS", minimum_tier="free", show_machine_id=True):
        try:
            safe_app = "".join(c if c.isalnum() else "_" for c in app_name).lower()
            minimum_tier = minimum_tier.lower()
            
            tier_levels = {"free": 1, "basic": 2, "pro": 3}
            
            machine_id = SupabaseGuard.get_machine_id()
            mid_display = machine_id if show_machine_id else None
            base_url = SupabaseGuard.SUPABASE_URL
            table = SupabaseGuard.TABLE_NAME
            
            query = urllib.parse.urlencode({
                "machine_id": "eq.{}".format(machine_id),
                "app_name": "eq.{}".format(safe_app),
                "select": "*"
            })
            url = "{}/rest/v1/{}?{}".format(base_url, table, query)
            
            data = SupabaseGuard.make_request(url, "GET")
            if data is None: 
                return False, "[ERROR] Gagal koneksi internet ke server lisensi.", {}
            
            final_data = None
            
            if not data:
                try:
                    hostname = platform.node()
                    username = getpass.getuser()
                    auto_client = "{} ({}) [QGIS]".format(hostname, username)
                except:
                    auto_client = "Unknown PC [QGIS]"

                payload = {
                    "machine_id": machine_id,
                    "app_name": safe_app,
                    "last_check": datetime.now(timezone.utc).isoformat(),
                    "tier": "free",
                    "status": "active",
                    "expiry_date": None,
                    "client_name": auto_client,
                    "version": SupabaseGuard.VERSION
                }
                post_url = "{}/rest/v1/{}".format(base_url, table)
                new_data = SupabaseGuard.make_request(post_url, "POST", payload)
                if not new_data: return False, "Gagal Registrasi Trial.", {}
                final_data = new_data[0]
            else:
                final_data = data[0]

                current_status = final_data.get("status", "").lower()
                if current_status in ["trial", "banned", "expired"]:
                    try:
                        patch_params = {
                            "machine_id": "eq.{}".format(machine_id), 
                            "app_name": "eq.{}".format(safe_app)
                        }
                        patch_query = urllib.parse.urlencode(patch_params)
                        patch_url = "{}/rest/v1/{}?{}".format(base_url, table, patch_query)
                        
                        patch_data = {
                            "status": "active",
                            "tier": "free",
                            "expiry_date": None,
                            "last_check": datetime.now(timezone.utc).isoformat(),
                            "version": SupabaseGuard.VERSION
                        }
                        SupabaseGuard.make_request(patch_url, "PATCH", patch_data)
                        
                        final_data["status"] = "active"
                        final_data["tier"] = "free"
                        final_data["expiry_date"] = None
                    except:
                        pass
                else:
                    q_upd = urllib.parse.urlencode({"machine_id": "eq.{}".format(machine_id), "app_name": "eq.{}".format(safe_app)})
                    SupabaseGuard.make_request("{}/rest/v1/{}?{}".format(base_url, table, q_upd), "PATCH", {
                        "last_check": datetime.now(timezone.utc).isoformat(),
                        "version": SupabaseGuard.VERSION
                    })

            _tier = final_data.get("tier", "").lower()
            _status = final_data.get("status", "").lower()
            _expiry = final_data.get("expiry_date")
            
            should_cleanup = False
            if _tier == "free" and _expiry is not None: should_cleanup = True
            if _status == "trial": should_cleanup = True
            if _tier == "pro": should_cleanup = True
            
            if should_cleanup:
                try:
                    patch_params = {
                        "machine_id": "eq.{}".format(machine_id), 
                        "app_name": "eq.{}".format(safe_app)
                    }
                    patch_query = urllib.parse.urlencode(patch_params)
                    patch_url = "{}/rest/v1/{}?{}".format(base_url, table, patch_query)
                    
                    patch_data = {
                        "status": "active",
                        "tier": "free",
                        "expiry_date": None,
                        "last_check": datetime.now(timezone.utc).isoformat(),
                        "version": SupabaseGuard.VERSION
                    }
                    
                    SupabaseGuard.make_request(patch_url, "PATCH", patch_data)
                    
                    final_data["status"] = "active"
                    final_data["tier"] = "free"
                    final_data["expiry_date"] = None
                    
                except Exception:
                    pass

            status = final_data.get("status", "trial").lower()
            tier = final_data.get("tier", "basic").lower()
            expiry = final_data.get("expiry_date")
            days_left = 0
            
            info = {
                "tier": tier,
                "status": status,
                "expiry": expiry
            }

            if status == "banned": 
                return False, SupabaseGuard.format_status_box("BANNED", expiry, 0, safe_app, tier, mid_display), info
            
            user_level = 1 
            
            if status == "trial":
                 if expiry:
                    try:
                        exp_date = datetime.strptime(expiry, "%Y-%m-%d")
                        now_date = datetime.now()
                        days_left = (exp_date - now_date).days
                        info["days_left"] = days_left
                        
                        if days_left > 0:
                            user_level = 3 
                        else:
                            user_level = 1 
                            status = "TRIAL EXPIRED (FREE MODE)" 
                    except: 
                        user_level = 1
                 else:
                    user_level = 3
            elif status == "active":
                 user_level = tier_levels.get(tier, 1)
            elif status == "expired":
                 user_level = 1
                 status = "SUBSCRIPTION EXPIRED (FREE MODE)"
            
            req_lev = tier_levels.get(minimum_tier, 1)
            
            if user_level < req_lev:
                  req_tier_name = minimum_tier.upper()
                  user_tier_name = "FREE"
                  if user_level == 2: user_tier_name = "BASIC"
                  elif user_level == 3: user_tier_name = "PRO"
                  
                  msg_tier = SupabaseGuard.format_status_box(status, expiry, days_left, safe_app, user_tier_name, mid_display)
                  
                  detail_msg = "\n[ACCESS DENIED] Fitur ini eksklusif untuk paket {}.".format(req_tier_name)
                  detail_msg += "\nPaket Anda saat ini: {}.".format(user_tier_name)
                  
                  return False, msg_tier + detail_msg, info
            
            msg = SupabaseGuard.format_status_box(status, expiry, days_left, safe_app, tier, mid_display)
            return True, msg, info

        except Exception as e:
            return False, "License Logic Error: {}".format(str(e)), {}
