# feedback/models.py
from django.db import models
from colorfield.fields import ColorField
from django.utils.html import format_html
import qrcode
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import (
    SquareModuleDrawer,
    GappedSquareModuleDrawer,
    CircleModuleDrawer,
    RoundedModuleDrawer,
    VerticalBarsDrawer,
    HorizontalBarsDrawer,
)
from qrcode.image.styles.colormasks import SolidFillColorMask
from io import BytesIO
import base64
import json
import numpy as np
from ckeditor.fields import RichTextField
from django.utils.translation import gettext_lazy as _ 

class Feedback(models.Model):
    rating = models.PositiveSmallIntegerField()
    comment = models.TextField(blank=True)
    contact = models.CharField(max_length=100, blank=True)  # Phone or email
    submitted_at = models.DateTimeField(auto_now_add=True)
    referrer = models.CharField(max_length=255, blank=True)
    ip_address = models.GenericIPAddressField(blank=True, null=True)

    def __str__(self):
        return f"{self.rating} stars - {self.contact or 'Anonymous'}"
 
class QRcodeGenerate(models.Model):
    MODULE_DRAWER_CHOICES = [
        ('square', 'Square'),
        ('gapped_square', 'Gapped Square'),
        ('circle', 'Circle'),
        ('rounded', 'Rounded'),
        ('vertical_bars', 'Vertical Bars'),
        ('horizontal_bars', 'Horizontal Bars'),
    ]

    EYE_DRAWER_CHOICES = [
        ('square', 'Square'),
        ('circle', 'Circle'),
        ('rounded', 'Rounded'),
    ]

    class Meta:
        verbose_name = "QR Code Generate"
        verbose_name_plural = "QR Code Generate"

    name = models.CharField(max_length=255)
    url = models.URLField()
    qr_size = models.PositiveIntegerField(default=10, help_text="Size of each box in the QR code")
    qr_color = ColorField(default='#000000', help_text="Color of the QR code")
    qr_background = ColorField(default='#FFFFFF', help_text="Background color of the QR code")
    module_drawer = models.CharField(max_length=20, choices=MODULE_DRAWER_CHOICES, default='square')
    eye_drawer = models.CharField(max_length=20, choices=EYE_DRAWER_CHOICES, default='square')

    def hex_to_rgb(self, hex_color):
        """Convert hex color string to RGB tuple."""
        hex_color = hex_color.lstrip('#')
        return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))

    def qr_code(self):
        # Map string choices to actual drawer classes
        module_drawer_mapping = {
            'square': SquareModuleDrawer(),
            'gapped_square': GappedSquareModuleDrawer(),
            'circle': CircleModuleDrawer(),
            'rounded': RoundedModuleDrawer(),
            'vertical_bars': VerticalBarsDrawer(),
            'horizontal_bars': HorizontalBarsDrawer(),
        }

        eye_drawer_mapping = {
            'square': SquareModuleDrawer(),
            'circle': CircleModuleDrawer(),
            'rounded': RoundedModuleDrawer(),
        }

        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_H,
            box_size=self.qr_size,
            border=4,
        )
        qr.add_data(self.url)
        qr.make(fit=True)

        # Convert hex colors to RGB tuples
        front_color = self.hex_to_rgb(self.qr_color)
        back_color = self.hex_to_rgb(self.qr_background)

        img = qr.make_image(
            image_factory=StyledPilImage,
            module_drawer=module_drawer_mapping.get(self.module_drawer, SquareModuleDrawer()),
            eye_drawer=eye_drawer_mapping.get(self.eye_drawer, SquareModuleDrawer()),
            color_mask=SolidFillColorMask(back_color=back_color, front_color=front_color),
        )

        buffer = BytesIO()
        img.save(buffer, format="PNG")
        img_str = base64.b64encode(buffer.getvalue()).decode()

        return format_html(
            '''
            <img src="data:image/png;base64,{}" width="150" height="150" id="qr-image"/>
            <br/>
            <a href="data:image/png;base64,{}" download="qr_code.png">
                <button type="button">Download QR Code</button>
            </a>
            <button type="button" onclick="printQRCode()">Print QR Code</button>
            <script>
                function printQRCode() {{
                    var img = document.getElementById('qr-image');
                    var w = window.open();
                    w.document.write('<img src="' + img.src + '" onload="window.print();window.close()" />');
                    w.document.close();
                }}
            </script>
            ''',
            img_str,
            img_str
        )

    qr_code.short_description = 'QR Code'


class FaceProfile(models.Model):
    name = models.CharField(max_length=100)
    phone_number = models.CharField(max_length=20, unique=True)
    face_image = models.ImageField(upload_to='faces/')
    face_encoding = models.TextField(blank=True, null=True)  # JSON encoded string
    created_at = models.DateTimeField(auto_now_add=True) 

    def set_encoding(self, encoding_array):
        self.face_encoding = json.dumps(encoding_array.tolist())

    def get_encoding(self):
        if self.face_encoding:
            return np.array(json.loads(self.face_encoding))
        return None

    def __str__(self):
        return self.name
    

class ChatCategory(models.Model):
    name = models.CharField(
        max_length=100,
        unique=True,
        null=True,
        blank=True,
        default=None,
        verbose_name=_("Category Name")
    )
    description = models.TextField(
        null=True,
        blank=True,
        default=None,
        verbose_name=_("Description")
    )
    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        related_name='subcategories',
        null=True,
        blank=True,
        default=None,
        verbose_name=_("Parent Category")
    )
    is_active = models.BooleanField(
        default=True,
        null=True,
        blank=True,
        verbose_name=_("Is Active")
    )
    code = models.CharField(
        max_length=50,
        unique=True,
        null=True,
        blank=True,
        default=None,
        verbose_name=_("Category Code")
    )

    def __str__(self):
        status = "Active" if self.is_active else "Inactive"
        return f"{self.name or 'Unnamed Category'} ({status})"

    def get_children(self):
        return self.subcategories.all()

    def is_root(self):
        return self.parent is None

    class Meta:
        verbose_name = _("Chat Category")
        verbose_name_plural = _("Chat Categories")

class PredefinedQA(models.Model):
    question = models.CharField(max_length=255, unique=True)
    answer = RichTextField() 
 # Replaced TextField with CKEditor's RichTextField
    category = models.ForeignKey(
        'ChatCategory',  # reference to the ChatCategory model
        on_delete=models.SET_NULL,  # If category is deleted, set the field to null
        null=True,  # Allows for optional category assignment
        blank=True,  # Makes it optional for users to assign a category
        related_name='predefined_qa',  # You can access all questions for a category via predefined_qa
        verbose_name="Category"
        
    )
    active = models.BooleanField(default=True)  # Add this line

    def __str__(self):
        return self.question

    class Meta:
        verbose_name = "Chat Bot"
        verbose_name_plural = "Chat Bots"



class ChatLog(models.Model):
    user_name = models.CharField(max_length=100)
    user_email = models.EmailField(blank=True, null=True)
    user_phone = models.CharField(max_length=20, blank=True, null=True)
    session_id = models.CharField(max_length=50, unique=True)  # to identify session/conversation
    conversation = models.TextField(default="[]")  # default empty JSON array as string
    timestamp = models.DateTimeField(auto_now=True)

    def get_conversation(self):
        try:
            return json.loads(self.conversation)
        except Exception:
            return []

    def __str__(self):
        return f"Chat from {self.user_name} at {self.timestamp}"
