from sqlalchemy_serializer import SerializerMixin
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from wtforms import SelectMultipleField

from sqlalchemy.orm import backref

from flask import Markup
from dateutil import relativedelta
from hiddifypanel.panel.database import db
import enum
import datetime
import uuid as uuid_mod
from enum import auto
from strenum import StrEnum

class ConfigCategory(StrEnum):
    admin=auto()
    branding=auto()
    general=auto()
    proxies=auto()
    domain_fronting=auto()
    telegram=auto()
    http=auto()
    tls=auto()
    ssfaketls=auto()
    shadowtls=auto()
    tuic=auto()
    ssr=auto()
    kcp=auto()
    hidden=auto()
    advanced=auto()
    too_advanced=auto()

class ConfigEnum(StrEnum):
    package_mode=auto()
    utls=auto()
    telegram_bot_token=auto()
    is_parent=auto()
    parent_panel=auto()
    unique_id=auto()
    cdn_forced_host=auto() # removed
    lang = auto()
    admin_lang = auto()
    admin_secret = auto()
    tls_ports = auto()
    http_ports = auto()
    kcp_ports = auto()
    kcp_enable = auto()
    decoy_domain = auto()
    proxy_path = auto()
    firewall = auto()
    netdata = auto()
    http_proxy_enable = auto()
    block_iran_sites = auto()
    allow_invalid_sni = auto()
    auto_update = auto()
    speed_test = auto()
    only_ipv4 = auto()

    shared_secret = auto()

    telegram_enable = auto()
    # telegram_secret=auto()
    telegram_adtag = auto()
    telegram_lib = auto()
    telegram_fakedomain = auto()

    v2ray_enable = auto()
    torrent_block = auto()

    ssfaketls_enable = auto()
    # ssfaketls_secret="ssfaketls_secret"
    ssfaketls_fakedomain = auto()

    shadowtls_enable = auto()
    # shadowtls_secret=auto()
    shadowtls_fakedomain = auto()

    tuic_enable = auto()
    tuic_port = auto()

    ssr_enable = auto()
    # ssr_secret="ssr_secret"
    ssr_fakedomain = auto()

    vmess_enable = auto()
    domain_fronting_domain = auto()
    domain_fronting_http_enable = auto()
    domain_fronting_tls_enable = auto()

    db_version = auto()

    branding_title=auto()
    branding_site=auto()
    branding_freetext=auto()
    not_found=auto()
    path_vmess=auto()
    path_vless=auto()
    path_trojan=auto()
    path_v2ray=auto()#deprecated
    path_ss=auto()

    path_ws=auto()
    path_tcp=auto()
    path_grpc=auto()

    # cdn_forced_host=auto()
    @classmethod
    def _missing_(cls, value):
      return cls.not_found #"key not found"
    def info(self):
        map = {
            self.path_vmess:{'category': ConfigCategory.too_advanced},
            self.path_vless:{'category': ConfigCategory.too_advanced},
            self.path_trojan:{'category': ConfigCategory.too_advanced},
            self.path_ss:{'category': ConfigCategory.hidden},
            self.path_tcp:{'category': ConfigCategory.too_advanced},
            self.path_ws:{'category': ConfigCategory.too_advanced},
            self.path_grpc:{'category': ConfigCategory.too_advanced},
            self.path_v2ray:{'category': ConfigCategory.hidden},

            self.utls: {'category': ConfigCategory.proxies},
            self.package_mode: {'category': ConfigCategory.advanced,'show_in_parent':True},
            self.telegram_bot_token: {'category': ConfigCategory.advanced,'show_in_parent':True},
            self.is_parent:{'category': ConfigCategory.hidden,'type':bool},
            self.parent_panel:{'category': ConfigCategory.advanced},
            self.unique_id:{'category': ConfigCategory.hidden,},
            self.cdn_forced_host:{'category': ConfigCategory.hidden,},
            self.branding_title:{'category': ConfigCategory.branding,'show_in_parent':True},
            self.branding_site:{'category': ConfigCategory.branding,'show_in_parent':True},
            self.branding_freetext:{'category': ConfigCategory.branding,'show_in_parent':True},
            self.not_found:{'category': ConfigCategory.hidden},
            self.admin_secret: {'category': ConfigCategory.admin,'show_in_parent':True},
            self.lang: {'category': ConfigCategory.branding,'show_in_parent':True},
            self.admin_lang: {'category': ConfigCategory.admin,'show_in_parent':True},
            self.tls_ports: {'category': ConfigCategory.hidden,'apply_mode':'apply'},#tls
            self.http_ports: {'category': ConfigCategory.hidden,'apply_mode':'apply'},#http
            self.kcp_ports: {'category': ConfigCategory.kcp,'apply_mode':'apply'},
            self.kcp_enable: {'category': ConfigCategory.kcp,'type':bool,'apply_mode':'apply'},
            self.decoy_domain: {'category': ConfigCategory.general,'apply_mode':'apply'},
            self.proxy_path: {'category': ConfigCategory.too_advanced,'apply_mode':'apply','show_in_parent':True},
            self.firewall: {'category': ConfigCategory.general,'type':bool,'apply_mode':'apply'},
            self.netdata: {'category': ConfigCategory.general,'type':bool,'apply_mode':'apply'},
            self.http_proxy_enable: {'category': ConfigCategory.http,'type':bool},
            self.block_iran_sites: {'category': ConfigCategory.proxies,'type':bool,'apply_mode':'apply'},
            self.allow_invalid_sni: {'category': ConfigCategory.tls,'type':bool,'apply_mode':'apply'},
            self.auto_update: {'category': ConfigCategory.general,'type':bool,'apply_mode':'apply','show_in_parent':True},
            self.speed_test: {'category': ConfigCategory.general,'type':bool,'apply_mode':'apply'},
            self.only_ipv4: {'category': ConfigCategory.general,'type':bool,'apply_mode':'apply'},
            self.torrent_block: {'category': ConfigCategory.general,'type':bool,'apply_mode':'apply'},

            self.shared_secret: {'category': ConfigCategory.proxies,'apply_mode':'apply'},

            self.telegram_enable: {'category': ConfigCategory.telegram,'type':bool,'apply_mode':'apply'},
            # telegram_secret:{'category':'general'},
            self.telegram_adtag: {'category': ConfigCategory.telegram,'apply_mode':'apply'},
            self.telegram_fakedomain: {'category': ConfigCategory.telegram,'apply_mode':'apply'},
            self.telegram_lib: {'category': ConfigCategory.telegram,'apply_mode':'reinstall'},

            self.v2ray_enable: {'category': ConfigCategory.proxies,'type':bool,'apply_mode':'apply'},

            self.ssfaketls_enable: {'category': ConfigCategory.ssfaketls,'type':bool,'apply_mode':'apply'},
            # ssfaketls_secret:{'category':'ssfaketls'},
            self.ssfaketls_fakedomain: {'category': ConfigCategory.ssfaketls,'apply_mode':'apply'},

            self.shadowtls_enable: {'category': ConfigCategory.shadowtls,'type':bool,'apply_mode':'apply'},
            # shadowtls_secret:{'category':'shadowtls'},
            self.shadowtls_fakedomain: {'category': ConfigCategory.shadowtls,'apply_mode':'apply'},

            self.tuic_enable: {'category': ConfigCategory.tuic,'type':bool,'apply_mode':'apply'},
            self.tuic_port: {'category': ConfigCategory.tuic,'apply_mode':'apply'},

            self.ssr_enable: {'category': ConfigCategory.ssr,'type':bool,'apply_mode':'apply'},
            # ssr_secret:{'category':'ssr'},
            self.ssr_fakedomain: {'category': ConfigCategory.ssr,'apply_mode':'apply'},

            self.vmess_enable: {'category': ConfigCategory.proxies,'type':bool},
            self.domain_fronting_domain: {'category': ConfigCategory.domain_fronting},
            self.domain_fronting_http_enable: {'category': ConfigCategory.domain_fronting,'type':bool},
            self.domain_fronting_tls_enable: {'category': ConfigCategory.domain_fronting,'type':bool},

            self.db_version: {'category': ConfigCategory.hidden},
        }
        return map[self]

    def category(self):
        return self.info()['category']
    def type(self):
        info=self.info()
        return info['type'] if 'type' in info else str
    def apply_mode(self):
        info=self.info()
        return info['apply_mode'] if 'apply_mode' in info else ''
    def show_in_parent(self):
        info=self.info()
        return info['show_in_parent'] if 'show_in_parent' in info else False