from hiddifypanel.models import BoolConfig,StrConfig,ConfigEnum,hconfig
import flask_babel,flask_babelex

# from flask_babelex import lazy_gettext as _
from flask_babelex import gettext as _
import wtforms as wtf
from flask_wtf import FlaskForm
from flask_bootstrap import SwitchField
from hiddifypanel.panel import hiddify
from flask_admin.base import expose
# from gettext import gettext as _
from wtforms.validators import Regexp,ValidationError

import re
from flask import render_template,current_app, Markup,redirect,url_for
from hiddifypanel.models import  User,Domain,DomainType,StrConfig,ConfigEnum,get_hconfigs
from hiddifypanel.panel.database import db
from wtforms.fields import *

from hiddifypanel.panel.hiddify import flash
from flask_classful import FlaskView

class QuickSetup(FlaskView):
    
        def index(self):
                return render_template('quick_setup.html', lang_form=get_lang_form(), form=get_quick_setup_form(),ipv4=hiddify.get_ip(4),ipv6=hiddify.get_ip(6),admin_link=admin_link(),show_domain_info=True)
        
        def post(self):
                quick_form=get_quick_setup_form()
                lang_form=get_lang_form()
                if lang_form.lang_submit.data:
                        if lang_form.validate_on_submit():
                                StrConfig.query.filter(StrConfig.key==ConfigEnum.lang,StrConfig.child_id==0).first().value=lang_form.admin_lang.data
                                StrConfig.query.filter(StrConfig.key==ConfigEnum.admin_lang,StrConfig.child_id==0).first().value=lang_form.admin_lang.data
                                db.session.commit()
                                
                                flask_babel.refresh()
                                flask_babelex.refresh()
                                # with flask_babel.force_locale(lang_form.admin_lang.data):
                                #         flask_babel.refresh()
                                #         flask_babelex.refresh()
                                flash((_('quicksetup.setlang.success')), 'success')
                        else:
                                flash((_('quicksetup.setlang.error')), 'danger')

                        return render_template('quick_setup.html', form=get_quick_setup_form(True),lang_form=get_lang_form(),admin_link=admin_link(),ipv4=hiddify.get_ip(4),ipv6=hiddify.get_ip(6),show_domain_info=False)                
                
                if quick_form.validate_on_submit():
                        sslip_dm=Domain.query.filter(Domain.domain==f'{hiddify.get_ip(4)}.sslip.io').delete()
                        db.session.add(Domain(domain=quick_form.domain.data.lower(),mode=DomainType.direct))
                        hiddify.bulk_register_configs([
                                        {"key":ConfigEnum.telegram_enable,"value":quick_form.enable_telegram.data},
                                        {"key":ConfigEnum.vmess_enable,"value":quick_form.enable_vmess.data},
                                        {"key":ConfigEnum.firewall,"value":quick_form.enable_firewall.data},
                                        {"key":ConfigEnum.block_iran_sites,"value":quick_form.block_iran_sites.data},
                                        {"key":ConfigEnum.decoy_domain,"value":quick_form.decoy_domain.data}
                                ])
                        
                        
                        db.session.commit()
                        # hiddify.flash_config_success()
                        proxy_path=hconfig(ConfigEnum.proxy_path)
                        # uuid=User.query.first().uuid
                        # userlink=f"<a class='btn btn-secondary share-link' target='_blank' href='https://{quick_form.domain.data}/{proxy_path}/{uuid}/'>{_('default user link')}</a>"
                        # flash((_('The default user link is %(link)s. To add or edit more users, please visit users from menu.',link=userlink)),'info')
                        
                        from . import Actions
                        action=Actions()
                        return action.reinstall(domain_changed=True)
                else:
                        flash(_('config.validation-error'), 'danger')
                return render_template('quick_setup.html', form=quick_form,lang_form=get_lang_form(True),ipv4=hiddify.get_ip(4),ipv6=hiddify.get_ip(6),admin_link=admin_link() ,show_domain_info=False)

def get_lang_form(empty=False):
        class LangForm(FlaskForm):
                admin_lang=wtf.fields.SelectField(_("config.admin_lang.label"),choices=[("en",_("lang.en")),("fa",_("lang.fa"))],description=_("config.admin_lang.description"),default=hconfig(ConfigEnum.admin_lang))
                # lang=wtf.fields.SelectField(_("config.lang.label"),choices=[("en",_("lang.en")),("fa",_("lang.fa"))],description=_("config.lang.description"),default=hconfig(ConfigEnum.lang))
                lang_submit=wtf.fields.SubmitField(_('Submit'))
        
        return LangForm(None)if empty else LangForm()
def get_quick_setup_form(empty=False):
        def get_used_domains():
                configs=get_hconfigs()
                domains=[]
                for c in configs:
                        if "domain" in c:
                                domains.append(configs[c])
                for d in Domain.query.all():
                        domains.append(d.domain)
                return domains
        class QuickSetupForm(FlaskForm):
                domain_regex="^([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})$"

                domain_validators=[wtf.validators.Regexp(domain_regex,re.IGNORECASE,_("config.Invalid domain")),
                                        validate_domain,
                                        wtf.validators.NoneOf([d.domain.lower() for d in Domain.query.all()],_("config.Domain already used")),
                                        wtf.validators.NoneOf([c.value.lower() for c in StrConfig.query.all() if "fakedomain" in c.key and c.key!=ConfigEnum.decoy_domain],_("config.Domain already used"))
                                        ]
                domain=wtf.fields.StringField(_("domain.domain"),domain_validators,description=_("domain.description"),render_kw={"class":"ltr", "pattern":domain_validators[0].regex.pattern,"title":domain_validators[0].message,"required":"","placeholder":"sub.domain.com"})
                enable_telegram=SwitchField(_("config.telegram_enable.label"),description=_("config.telegram_enable.description"),default=hconfig(ConfigEnum.telegram_enable))
                enable_firewall=SwitchField(_("config.firewall.label"),description=_("config.firewall.description"),default=hconfig(ConfigEnum.firewall))
                block_iran_sites=SwitchField(_("config.block_iran_sites.label"),description=_("config.block_iran_sites.description"),default=hconfig(ConfigEnum.block_iran_sites))
                enable_vmess=SwitchField(_("config.vmess_enable.label"),description=_("config.vmess_enable.description"),default=hconfig(ConfigEnum.vmess_enable))
                decoy_domain=wtf.fields.StringField(_("config.decoy_domain.label"),description=_("config.decoy_domain.description"),default=hconfig(ConfigEnum.decoy_domain),validators=[wtf.validators.Regexp(domain_regex,re.IGNORECASE,_("config.Invalid domain")),hiddify.validate_domain_exist])
                submit=wtf.fields.SubmitField(_('Submit'))

                
        
        return QuickSetupForm(None) if empty else QuickSetupForm()

def validate_domain(form,field):
        domain=field.data
        dip=hiddify.get_domain_ip(domain)
        if dip==None:
                raise ValidationError(_("Domain can not be resolved! there is a problem in your domain"))

        myip=hiddify.get_ip(4)
        if dip and myip!=dip:
                raise ValidationError(_("Domain (%(domain)s)-> IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode",server_ip=myip,domain_ip=dip,domain=domain))
def admin_link():
        return "https://"+Domain.query.first().domain+hiddify.get_admin_path()