import django_tables2 as tables
from django.utils.translation import gettext_lazy as _
from django_tables2.utils import Accessor

from dcim.models import Rack, RackGroup, RackReservation, RackRole, RackType
from netbox.tables import OrganizationalModelTable, PrimaryModelTable, columns
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin

from .template_code import OUTER_UNIT, WEIGHT

__all__ = (
    'RackGroupTable',
    'RackReservationTable',
    'RackRoleTable',
    'RackTable',
    'RackTypeTable',
)


class RackGroupTable(OrganizationalModelTable):
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True,
    )
    rack_count = columns.LinkedCountColumn(
        viewname='dcim:rack_list',
        url_params={'group_id': 'pk'},
        verbose_name=_('Racks'),
    )
    tags = columns.TagColumn(
        url_name='dcim:rackgroup_list',
    )

    class Meta(OrganizationalModelTable.Meta):
        model = RackGroup
        fields = (
            'pk', 'id', 'name', 'rack_count', 'description', 'slug', 'comments', 'tags', 'actions', 'created',
            'last_updated',
        )
        default_columns = ('pk', 'name', 'rack_count', 'description')


class RackRoleTable(OrganizationalModelTable):
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True
    )
    rack_count = columns.LinkedCountColumn(
        viewname='dcim:rack_list',
        url_params={'role_id': 'pk'},
        verbose_name=_('Racks')
    )
    color = columns.ColorColumn(
        verbose_name=_('Color'),
    )
    tags = columns.TagColumn(
        url_name='dcim:rackrole_list'
    )

    class Meta(OrganizationalModelTable.Meta):
        model = RackRole
        fields = (
            'pk', 'id', 'name', 'rack_count', 'color', 'description', 'slug', 'comments', 'tags', 'actions', 'created',
            'last_updated',
        )
        default_columns = ('pk', 'name', 'rack_count', 'color', 'description')


class RackTypeTable(PrimaryModelTable):
    model = tables.Column(
        verbose_name=_('Model'),
        linkify=True
    )
    manufacturer = tables.Column(
        verbose_name=_('Manufacturer'),
        linkify=True
    )
    u_height = tables.TemplateColumn(
        template_code="{{ value }}U",
        verbose_name=_('Height')
    )
    outer_width = columns.TemplateColumn(
        template_code=OUTER_UNIT,
        verbose_name=_('Outer Width')
    )
    outer_height = columns.TemplateColumn(
        template_code=OUTER_UNIT,
        verbose_name=_('Outer Height')
    )
    outer_depth = columns.TemplateColumn(
        template_code=OUTER_UNIT,
        verbose_name=_('Outer Depth')
    )
    weight = columns.TemplateColumn(
        verbose_name=_('Weight'),
        template_code=WEIGHT,
        order_by=('_abs_weight', 'weight_unit')
    )
    max_weight = columns.TemplateColumn(
        verbose_name=_('Max Weight'),
        template_code=WEIGHT,
        order_by=('_abs_max_weight', 'weight_unit')
    )
    rack_count = columns.LinkedCountColumn(
        viewname='dcim:rack_list',
        url_params={'rack_type_id': 'pk'},
        verbose_name=_('Rack Count'),
    )
    tags = columns.TagColumn(
        url_name='dcim:rack_list'
    )

    class Meta(PrimaryModelTable.Meta):
        model = RackType
        fields = (
            'pk', 'id', 'model', 'manufacturer', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
            'outer_height', 'outer_depth', 'mounting_depth', 'weight', 'max_weight', 'description', 'comments',
            'rack_count', 'tags', 'created', 'last_updated',
        )
        default_columns = (
            'pk', 'model', 'manufacturer', 'type', 'u_height', 'description', 'rack_count',
        )


class RackTable(TenancyColumnsMixin, ContactsColumnMixin, PrimaryModelTable):
    name = tables.Column(
        verbose_name=_('Name'),
        linkify=True
    )
    location = tables.Column(
        verbose_name=_('Location'),
        linkify=True
    )
    site = tables.Column(
        verbose_name=_('Site'),
        linkify=True
    )
    group = tables.Column(
        verbose_name=_('Group'),
        linkify=True,
    )
    status = columns.ChoiceFieldColumn(
        verbose_name=_('Status'),
    )
    role = columns.ColoredLabelColumn(
        verbose_name=_('Role'),
    )
    manufacturer = tables.Column(
        verbose_name=_('Manufacturer'),
        accessor=Accessor('rack_type__manufacturer'),
        linkify=True
    )
    rack_type = tables.Column(
        linkify=True,
        verbose_name=_('Type')
    )
    u_height = tables.TemplateColumn(
        template_code="{{ value }}U",
        verbose_name=_('Height')
    )
    device_count = columns.LinkedCountColumn(
        viewname='dcim:device_list',
        url_params={'rack_id': 'pk'},
        verbose_name=_('Devices')
    )
    get_utilization = columns.UtilizationColumn(
        orderable=False,
        verbose_name=_('Space')
    )
    get_power_utilization = columns.UtilizationColumn(
        orderable=False,
        verbose_name=_('Power')
    )
    tags = columns.TagColumn(
        url_name='dcim:rack_list'
    )
    outer_width = columns.TemplateColumn(
        template_code=OUTER_UNIT,
        verbose_name=_('Outer Width')
    )
    outer_height = columns.TemplateColumn(
        template_code=OUTER_UNIT,
        verbose_name=_('Outer Height')
    )
    outer_depth = columns.TemplateColumn(
        template_code=OUTER_UNIT,
        verbose_name=_('Outer Depth')
    )
    weight = columns.TemplateColumn(
        verbose_name=_('Weight'),
        template_code=WEIGHT,
        order_by=('_abs_weight', 'weight_unit')
    )
    max_weight = columns.TemplateColumn(
        verbose_name=_('Max Weight'),
        template_code=WEIGHT,
        order_by=('_abs_max_weight', 'weight_unit')
    )

    class Meta(PrimaryModelTable.Meta):
        model = Rack
        fields = (
            'pk', 'id', 'name', 'site', 'location', 'group', 'status', 'facility_id', 'tenant', 'tenant_group', 'role',
            'rack_type', 'serial', 'asset_tag', 'form_factor', 'u_height', 'starting_unit', 'width', 'outer_width',
            'outer_height', 'outer_depth', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'comments',
            'device_count', 'get_utilization', 'get_power_utilization', 'description', 'contacts',
            'tags', 'created', 'last_updated',
        )
        default_columns = (
            'pk', 'name', 'site', 'location', 'group', 'status', 'facility_id', 'tenant', 'role', 'rack_type',
            'u_height', 'device_count', 'get_utilization',
        )


class RackReservationTable(TenancyColumnsMixin, PrimaryModelTable):
    reservation = tables.Column(
        verbose_name=_('Reservation'),
        accessor='pk',
        linkify=True
    )
    site = tables.Column(
        verbose_name=_('Site'),
        accessor=Accessor('rack__site'),
        linkify=True
    )
    location = tables.Column(
        verbose_name=_('Location'),
        accessor=Accessor('rack__location'),
        linkify=True
    )
    group = tables.Column(
        verbose_name=_('Group'),
        accessor=Accessor('rack__group'),
        linkify=True
    )
    rack = tables.Column(
        verbose_name=_('Rack'),
        linkify=True
    )
    unit_list = tables.Column(
        orderable=False,
        verbose_name=_('Units')
    )
    unit_count = tables.Column(
        verbose_name=_("Total U's")
    )
    status = columns.ChoiceFieldColumn(
        verbose_name=_('Status'),
    )
    tags = columns.TagColumn(
        url_name='dcim:rackreservation_list'
    )

    class Meta(PrimaryModelTable.Meta):
        model = RackReservation
        fields = (
            'pk', 'id', 'reservation', 'site', 'location', 'group', 'rack', 'unit_list', 'unit_count', 'status',
            'user', 'tenant', 'tenant_group', 'description', 'comments', 'tags', 'actions', 'created', 'last_updated',
        )
        default_columns = (
            'pk', 'reservation', 'site', 'rack', 'unit_list', 'unit_count', 'status', 'user', 'description',
        )
