from django import forms
from django.utils.translation import gettext as _
from utilities.forms.rendering import FieldSet
from extras.forms.model_forms import CustomFieldForm, get_field_value
from .cf_types import ExtendedCustomFieldTypeChoices
from .models import TagidCustomField
from utilities.templatetags.builtins.tags import customfield_value as _orig_customfield_value, register
from django.utils.safestring import mark_safe
from django.utils.html import escape

# ---------- helpers ----------
def _coerce_length(v, default=6, lo=1, hi=64):
    try:
        n = int(v)
    except Exception:
        return default
    return max(lo, min(n, hi))

# def _get_field_type(form):
#     # get_field_value peut retourner None selon le contexte (type disabled, POST HTMX, etc.)
#     return get_field_value(form, "type") or getattr(form.instance, "type", None)


# ---------- patch __init__ ----------
_orig_init = CustomFieldForm.__init__

def _new_init(self, *args, **kwargs):
    _orig_init(self, *args, **kwargs)

    # field_type = _get_field_type(self)
    field_type = get_field_value(self, "type")
    if field_type != ExtendedCustomFieldTypeChoices.TYPE_TAGID:
        return

    # Préremplissage depuis la config liée (si elle existe)
    prefix_initial = ""
    suffix_initial = ""
    length_initial = 6
    printer_name_initial = ""
    cups_host_initial = ""
    printer_opt_initial = ""
    printer_count_initial = 1

    # if getattr(self, "instance", None) and getattr(self.instance, "pk", None):
    if self.instance and self.instance.pk:
        try:
            cfg = self.instance.tagid_config  # via related_name='tagid_config'
            prefix_initial = cfg.prefix or ""
            suffix_initial = cfg.suffix or ""
            length_initial = cfg.length or 6
            printer_name_initial = cfg.printer_name or ""
            cups_host_initial = cfg.cups_host or ""
            printer_opt_initial = cfg.printer_opt or ""
            printer_count_initial = cfg.printer_count or 1
        except TagidCustomField.DoesNotExist:
            pass

    self.fields["prefix"] = forms.CharField(
        label=_("Préfixe"),
        required=False,
        initial=prefix_initial,
        widget=forms.TextInput(attrs={"class": "form-control"})
    )
    self.fields["suffix"] = forms.CharField(
        label=_("Suffixe"),
        required=False,
        initial=suffix_initial,
        widget=forms.TextInput(attrs={"class": "form-control"})
    )
    self.fields["length"] = forms.IntegerField(
        label=_("Longueur"),
        required=True,
        min_value=1, max_value=64,
        initial=length_initial,
        widget=forms.NumberInput(attrs={"class": "form-control"})
    )

    self.fields["printer_name"] = forms.CharField(
        label=_("Imprimante"),
        required=False,
        initial=printer_name_initial,
        widget=forms.TextInput(attrs={"class": "form-control"})
    )
    self.fields["cups_host"] = forms.CharField(
        label=_("Serveur d'impression"),
        required=False,
        initial=cups_host_initial,
        widget=forms.TextInput(attrs={"class": "form-control"})
    )
    self.fields["printer_opt"] = forms.CharField(
        label=_("Options d'impression"),
        required=False,
        initial=printer_opt_initial,
        help_text="Pour mettre plusieurs options séparez-les avec un \"/\".",
        widget=forms.TextInput(attrs={"class": "form-control"})
    )

    self.fields["printer_count"] = forms.IntegerField(
        label=_("Nombre de pages"),
        required=True,
        min_value=1,
        initial=printer_count_initial,
        widget=forms.NumberInput(attrs={"class": "form-control"})
    )

    self.fieldsets = (
        self.fieldsets[0],
        FieldSet("prefix", "suffix", "length","printer_name","cups_host","printer_opt","printer_count", name=_("Paramètres Tag ID")),
        *self.fieldsets[1:],
    )

CustomFieldForm.__init__ = _new_init


# ---------- patch save() ----------
_orig_save = CustomFieldForm.save

def _safe_get(form, key, default=""):
    # Si le champ a été correctement bound : cleaned_data
    if hasattr(form, "cleaned_data") and key in form.cleaned_data:
        return form.cleaned_data.get(key, default)
    # Sinon, on se rabat sur les données brutes du POST
    return (form.data.get(key, default) if hasattr(form, "data") else default)

def _new_save(self, *args, **kwargs):

    obj = _orig_save(self, *args, **kwargs)

    # Lire le type depuis l'instance fraîchement sauvée (source de vérité)
    field_type = getattr(obj, "type", None)
    if field_type == ExtendedCustomFieldTypeChoices.TYPE_TAGID:
        prefix = (_safe_get(self, "prefix", "") or "").strip()
        suffix = (_safe_get(self, "suffix", "") or "").strip()
        length = _coerce_length(_safe_get(self, "length", 6), default=6, lo=1, hi=64)
        printer_name =  (_safe_get(self, "printer_name", "") or "").strip()
        cups_host = (_safe_get(self, "cups_host", "") or "").strip()
        printer_opt = (_safe_get(self, "printer_opt", "") or "").strip()
        printer_count = (_safe_get(self,"printer_count",1))

        
        cfg, _ = TagidCustomField.objects.get_or_create(tag_id=obj)
        cfg.prefix = prefix
        cfg.suffix = suffix
        cfg.length = length
        cfg.printer_name = printer_name
        cfg.cups_host = cups_host
        cfg.printer_opt = printer_opt
        cfg.printer_count = printer_count
        cfg.save()
    else:
        # Si le type a changé, nettoyer l'éventuelle config
        try:
            obj.tagid_config.delete()
        except Exception:
            pass

    return obj

CustomFieldForm.save = _new_save


@register.inclusion_tag('builtins/customfield_value.html')
def customfield_value(customfield, value):
    if customfield.type == "tagid":
        value = mark_safe(escape(value) + ' <button type="button" class="btn btn-cyan ml-20" data-cf-id="'+str(customfield.id)+'" data-value="'+escape(value)+'" onclick="netbox_tag_id_print(event.target);"><i class="mdi mdi-printer"></i>  Imprimer</button>')

    return _orig_customfield_value(customfield, value)


