"""
This is the models module for api.
"""

from datetime import timedelta
from django.contrib.auth.models import AbstractUser
from django.db import models
from .managers import CustomUserManager
from django.utils import timezone
import pyotp


class User(AbstractUser):
    address = models.CharField(max_length=255, blank=True)
    email = models.EmailField(blank=True, null=True, unique=True)
    mobile = models.CharField(max_length=255, blank=True, unique=True, null=True)
    designation = models.CharField(max_length=255, blank=True)
    acc_no = models.CharField(max_length=255, blank=True)
    id_card = models.CharField(max_length=255, blank=True, unique=True, null=True)
    verified = models.BooleanField(default=False)
    dob = models.DateField(blank=True, null=True)
    terms_accepted = models.BooleanField(default=False)
    policy_accepted = models.BooleanField(default=False)
    wallet_balance = models.FloatField(default=0.0)
    ninja_user_id = models.CharField(max_length=255, blank=True)
    atoll = models.ForeignKey(
        "Atoll", on_delete=models.SET_NULL, null=True, blank=True, related_name="users"
    )
    island = models.ForeignKey(
        "Island", on_delete=models.SET_NULL, null=True, blank=True, related_name="users"
    )
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)

    def get_all_fields(self, instance):
        return [field.name for field in instance.get_fields()]

    objects = CustomUserManager()


class TemporaryUser(models.Model):
    t_id = models.AutoField(primary_key=True)
    t_username = models.CharField(max_length=255, unique=True, blank=True, null=True)
    t_first_name = models.CharField(max_length=255, blank=True)
    t_last_name = models.CharField(max_length=255, blank=True)
    t_address = models.CharField(max_length=255, blank=True)
    t_email = models.EmailField(blank=True, null=True, unique=True)
    t_mobile = models.CharField(max_length=255, blank=True, unique=True, null=True)
    t_designation = models.CharField(max_length=255, blank=True)
    t_acc_no = models.CharField(max_length=255, blank=True)
    t_id_card = models.CharField(max_length=255, blank=True, unique=True, null=True)
    t_verified = models.BooleanField(default=False)
    t_dob = models.DateField(blank=True, null=True)
    t_terms_accepted = models.BooleanField(default=False)
    t_policy_accepted = models.BooleanField(default=False)
    t_wallet_balance = models.FloatField(default=0.0)
    t_ninja_user_id = models.CharField(max_length=255, blank=True)
    t_atoll = models.ForeignKey(
        "Atoll",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="temp_users",
    )
    t_island = models.ForeignKey(
        "Island",
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name="temp_users",
    )
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)

    def get_all_fields(self, instance):
        return [field.name for field in instance.get_fields()]

    otp_secret = models.CharField(max_length=50, default=pyotp.random_base32)
    otp_verified = models.BooleanField(default=False)

    def generate_otp(self):
        totp = pyotp.TOTP(self.otp_secret, interval=1800)
        return totp.now()

    def verify_otp(self, otp):
        totp = pyotp.TOTP(self.otp_secret, interval=1800)
        return totp.verify(otp)

    def is_expired(self):
        return self.created_at < timezone.now() - timedelta(minutes=5)

    class Meta:
        verbose_name = "Temporary User"
        verbose_name_plural = "Temporary Users"

    def __str__(self) -> str:
        return str(self.t_username)


class Atoll(models.Model):
    name = models.CharField(max_length=255, unique=True)
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name


class Island(models.Model):
    atoll = models.ForeignKey(Atoll, on_delete=models.CASCADE, related_name="islands")
    name = models.CharField(max_length=255, unique=True)
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name