from django.contrib.auth.models import User
from django.contrib.gis.db import models as gis_models
from django.db import models
from postamates.settings import SRID
from service.enums import PointStatus, MatchingStatus

User._meta.get_field('email')._unique = True


class AbstractPlacementPoint(models.Model):
    class Meta:
        abstract = True

    STATUS_CHOICES = [(tag.name, tag.value) for tag in PointStatus]
    address = models.TextField(null=True, blank=True, verbose_name='Адрес')
    name = models.TextField(null=True, blank=True, verbose_name='Название')
    postamat_id = models.IntegerField(unique=True, null=True, blank=True, verbose_name='ID  постамата')
    category = models.TextField(null=True, blank=True, verbose_name='Категория')
    status = models.TextField(choices=STATUS_CHOICES, null=True, blank=True, verbose_name='Статус')
    start_date = models.DateTimeField(null=True, blank=True)
    age_day = models.IntegerField(null=True, blank=True, verbose_name='Возраст')
    prediction_first = models.IntegerField(null=True, blank=True, verbose_name='Прогноз начальный')
    prediction_current = models.IntegerField(null=True, blank=True, verbose_name='Прогноз текущий')
    plan_first = models.IntegerField(null=True, blank=True, verbose_name='Плановый показатель начальный')
    plan_current = models.IntegerField(null=True, blank=True, verbose_name='Плановый показатель текущий')
    fact = models.IntegerField(null=True, blank=True, verbose_name='Фактический показатель')
    fact_raw = models.IntegerField(null=True, blank=True)
    delta_first = models.IntegerField(null=True, blank=True, verbose_name='Разница начальная')
    delta_current = models.IntegerField(null=True, blank=True, verbose_name='Разница текущая')
    sample_trn = models.BooleanField(null=True, blank=True)
    flat_cnt = models.IntegerField(null=True, blank=True, verbose_name='Количество квартир')
    year_bld = models.IntegerField(null=True, blank=True, verbose_name='Год постройки')
    levels = models.IntegerField(null=True, blank=True)
    enrg_cls = models.TextField(null=True, blank=True)
    mat_nes = models.TextField(null=True, blank=True)
    doors = models.IntegerField(null=True, blank=True)
    flats_cnt = models.IntegerField(null=True, blank=True)
    popul_home = models.IntegerField(null=True, blank=True)
    popul_job = models.IntegerField(null=True, blank=True)
    other_post_cnt = models.IntegerField(null=True, blank=True)
    target_post_cnt = models.IntegerField(null=True, blank=True)
    yndxfood_cnt = models.IntegerField(null=True, blank=True)
    yndxfood_sum = models.IntegerField(null=True, blank=True)
    yndxfood_cnt_cst = models.IntegerField(null=True, blank=True)
    district = models.ForeignKey('AO', on_delete=models.CASCADE, null=True, blank=True)
    area = models.ForeignKey('Rayon', on_delete=models.CASCADE, null=True, blank=True)
    geometry = gis_models.PointField(srid=SRID, null=True, verbose_name='Координаты')
    is_vis = models.BooleanField(null=True, blank=True)
    subject_rf = models.TextField(null=True, blank=True)
    city = models.TextField(null=True, blank=True)
    street = models.TextField(null=True, blank=True)
    house_number = models.TextField(null=True, blank=True)
    entrance = models.TextField(null=True, blank=True)
    post_code = models.TextField(null=True, blank=True)
    metro_dist = models.FloatField(null=True, blank=True)
    target_dist = models.FloatField(null=True, blank=True)
    property_price_bargains = models.FloatField(null=True, blank=True)
    property_price_offers = models.FloatField(null=True, blank=True)
    property_mean_floor = models.FloatField(null=True, blank=True)
    property_era = models.TextField(null=True, blank=True)
    business_activity = models.IntegerField(null=True, blank=True)
    bc_cnt = models.IntegerField(null=True, blank=True)
    tc_cnt = models.IntegerField(null=True, blank=True)
    rival_pvz_cnt = models.IntegerField(null=True, blank=True)
    rival_post_cnt = models.IntegerField(null=True, blank=True)
    flats_cnt_2 = models.IntegerField(null=True, blank=True)
    school_cnt = models.IntegerField(null=True, blank=True)
    kindergar_cnt = models.IntegerField(null=True, blank=True)
    public_stop_cnt = models.IntegerField(null=True, blank=True)
    sport_center_cnt = models.IntegerField(null=True, blank=True)
    pharmacy_cnt = models.IntegerField(null=True, blank=True)
    supermarket_cnt = models.IntegerField(null=True, blank=True)
    supermarket_premium_cnt = models.IntegerField(null=True, blank=True)
    clinic_cnt = models.IntegerField(null=True, blank=True)
    bank_cnt = models.IntegerField(null=True, blank=True)
    reca_cnt = models.IntegerField(null=True, blank=True)
    lab_cnt = models.IntegerField(null=True, blank=True)
    culture_cnt = models.IntegerField(null=True, blank=True)
    attraction_cnt = models.IntegerField(null=True, blank=True)
    mfc_cnt = models.IntegerField(null=True, blank=True)
    target_cnt_ao_mean = models.FloatField(null=True, blank=True)
    target_cnt_nearby_mean = models.FloatField(null=True, blank=True)
    target_age_nearby_mean = models.FloatField(null=True, blank=True)


class PlacementPoint(AbstractPlacementPoint):
    class Meta:
        verbose_name = 'Точка'
        verbose_name_plural = 'Точки'
        ordering = ('id',)


class PrePlacementPoint(AbstractPlacementPoint):
    class Meta:
        ordering = ('id',)

    MATCHING_CHOICES = [(tag.name, tag.value) for tag in MatchingStatus]
    matching_status = models.TextField(null=True, blank=True, choices=MATCHING_CHOICES)


class AO(models.Model):
    class Meta:
        verbose_name = 'АО'
        verbose_name_plural = 'АО'

    name = models.TextField(null=True, blank=True, verbose_name='Округ')
    polygon = gis_models.MultiPolygonField(null=True, srid=SRID)


class Rayon(models.Model):
    class Meta:
        verbose_name = 'Район'
        verbose_name_plural = 'Районы'

    name = models.TextField(null=True, blank=True, verbose_name='Район')
    AO = models.ForeignKey('AO', related_name='rayons', on_delete=models.CASCADE)
    polygon = gis_models.MultiPolygonField(null=True, srid=SRID)


class Post_and_pvz(models.Model):
    class Meta:
        verbose_name = 'Постамат или ПВЗ'
        verbose_name_plural = 'Постаматы и ПВЗ'
        ordering = ('id',)

    wkt = gis_models.PointField(srid=SRID, null=True)
    category = models.ForeignKey('Post_and_pvzCategory', default=None, related_name='post_and_pvz',
                                 on_delete=models.CASCADE)
    group = models.ForeignKey('Post_and_pvzGroup', default=None, related_name='post_and_pvz', on_delete=models.CASCADE)
    visible = models.BooleanField(default=True)
    include_in_ml = models.BooleanField(default=True)


class OtherObjects(models.Model):
    class Meta:
        verbose_name = 'Прочий объект'
        verbose_name_plural = 'Прочие объекты'
        ordering = ('id',)

    wkt = gis_models.PointField(srid=SRID, null=True)
    category = models.ForeignKey('OtherObjectsCategory', default=None, related_name='other_objects',
                                 on_delete=models.CASCADE)
    group = models.ForeignKey('OtherObjectsGroup', default=None, related_name='other_objects', on_delete=models.CASCADE)
    param1 = models.FloatField(blank=True, null=True)
    param2 = models.TextField(blank=True, null=True)
    param3 = models.FloatField(blank=True, null=True)
    param4 = models.FloatField(blank=True, null=True)
    visible = models.BooleanField(default=True)


class Post_and_pvzCategory(models.Model):
    class Meta:
        verbose_name = 'категория постаматов и ПВЗ'
        verbose_name_plural = 'Категории постаматов и ПВЗ'

    def __str__(self):
        return self.name

    name = models.TextField(null=False, blank=False, verbose_name='Название слоя')
    image = models.ImageField(blank=True, null=True, default=None, upload_to='post_and_pvz_category_images/',
                              verbose_name='Картинка')
    visible = models.BooleanField(default=True)
    include_in_ml = models.BooleanField(default=True)


class Post_and_pvzGroup(models.Model):
    class Meta:
        verbose_name = 'группа постаматов и ПВЗ'
        verbose_name_plural = 'Группы постаматов и ПВЗ'

    def __str__(self):
        return self.category.name + ' ' + self.name

    name = models.TextField(null=False, blank=False, verbose_name='Название группы')
    category = models.ForeignKey('Post_and_pvzCategory', default=None, related_name='groups',
                                 on_delete=models.CASCADE)
    image = models.ImageField(blank=True, null=True, upload_to='post_and_pvz_group_images/', verbose_name='Картинка')
    visible = models.BooleanField(default=True)
    include_in_ml = models.BooleanField(default=True)


class OtherObjectsCategory(models.Model):
    class Meta:
        verbose_name = 'категория прочих объектов'
        verbose_name_plural = 'Категории прочих объектов'

    def __str__(self):
        return self.name

    name = models.TextField(null=False, blank=False, verbose_name='Название слоя')
    image = models.ImageField(blank=True, null=True, default=None, upload_to='other_objects_category_images/',
                              verbose_name='Картинка')
    visible = models.BooleanField(default=True)


class OtherObjectsGroup(models.Model):
    class Meta:
        verbose_name = 'группа прочих объектов'
        verbose_name_plural = 'Группы прочих объектов'

    def __str__(self):
        return self.category.name + ' ' + self.name

    name = models.TextField(null=False, blank=False, verbose_name='Название группы')
    category = models.ForeignKey('OtherObjectsCategory', default=None, related_name='groups',
                                 on_delete=models.CASCADE)
    image = models.ImageField(blank=True, null=True, upload_to='other_objects_group_images/', verbose_name='Картинка')
    visible = models.BooleanField(default=True)


class PlacementPointPVZDistance(models.Model):
    placement_point = models.ForeignKey('PlacementPoint', default=None, on_delete=models.CASCADE)
    pvz_postamates_group = models.ForeignKey('Post_and_pvzGroup', default=None, on_delete=models.CASCADE)
    dist = models.FloatField(blank=True, null=True, default=None)


class PrePlacementPointPVZDistance(models.Model):
    placement_point = models.ForeignKey('PrePlacementPoint', default=None, on_delete=models.CASCADE)
    pvz_postamates_group = models.ForeignKey('Post_and_pvzGroup', default=None, on_delete=models.CASCADE)
    dist = models.FloatField(blank=True, null=True, default=None)


class TaskStatus(models.Model):
    class Meta:
        verbose_name = 'Статус фоновых задач'
        verbose_name_plural = 'Статус фоновых задач'

    def __str__(self):
        return self.task_name

    task_name = models.TextField(blank=False, unique=True, verbose_name='Название задачи')
    status = models.TextField(blank=True, null=True, verbose_name='Статус выполнения')


class LastMLCall(models.Model):
    dt = models.DateTimeField(auto_now_add=True)


class TempFiles(models.Model):
    data = models.TextField(blank=False, null=False)


class RaschetGroups(models.Model):
    obj_id = models.IntegerField(null=False, blank=False)


class RaschetObjects(models.Model):
    obj_id = models.IntegerField(null=False, blank=False)
