from django.contrib.auth.decorators import login_required
from accounts.utils import safe_form, sanitize_workbook, parse_int
from django.shortcuts import get_object_or_404, redirect, render
from django.http import HttpResponse
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font
from openpyxl.utils import get_column_letter

from .models import Facility

@login_required(login_url='login')
def facility_list(request):
    facilities = Facility.objects.all()

    search = request.GET.get('search', '').strip()

    if search:
        facilities = facilities.filter(
            name__icontains=search
        ) | facilities.filter(
            code__icontains=search
        ) | facilities.filter(
            building__icontains=search
        ) | facilities.filter(
            room_number__icontains=search
        )

    context = {
        'facilities': facilities,
        'search': search,
    }

    return render(
        request,
        'facilities/facility_list.html',
        context
    )


@login_required(login_url='login')
@safe_form
def facility_create(request):

    if request.method == 'POST':

        name = request.POST.get('name', '').strip()
        facility_type = request.POST.get('facility_type', '')
        building = request.POST.get('building', '').strip()
        floor = request.POST.get('floor', '').strip()
        room_number = request.POST.get('room_number', '').strip()
        capacity = request.POST.get('capacity', '').strip()
        responsible_person = request.POST.get(
            'responsible_person',
            ''
        ).strip()
        description = request.POST.get(
            'description',
            ''
        ).strip()
        status = request.POST.get(
            'status',
            'ACTIVE'
        )

        Facility.objects.create(
            name=name,
            facility_type=facility_type,
            building=building,
            floor=floor,
            room_number=room_number,
            capacity=int(capacity) if capacity else None,
            responsible_person=responsible_person,
            description=description,
            status=status,
        )

        return redirect('facility_list')

    context = {
    'facility_types': Facility.FACILITY_TYPES,
    'status_choices': Facility.STATUS_CHOICES,
    'floor_choices': Facility.FLOOR_CHOICES,
}

    return render(
        request,
        'facilities/facility_form.html',
        context
    )

@login_required(login_url='login')
@safe_form
def facility_update(request, pk):
    facility = get_object_or_404(
        Facility,
        pk=pk
    )

    if request.method == 'POST':
        facility.code = request.POST.get(
            'code',
            ''
        ).strip()

        facility.name = request.POST.get(
            'name',
            ''
        ).strip()

        facility.facility_type = request.POST.get(
            'facility_type',
            ''
        )

        facility.building = request.POST.get(
            'building',
            ''
        ).strip()

        facility.floor = request.POST.get(
            'floor',
            ''
        ).strip()

        facility.room_number = request.POST.get(
            'room_number',
            ''
        ).strip()

        capacity = request.POST.get(
            'capacity',
            ''
        ).strip()

        facility.capacity = (
            int(capacity)
            if capacity
            else None
        )

        facility.responsible_person = request.POST.get(
            'responsible_person',
            ''
        ).strip()

        facility.description = request.POST.get(
            'description',
            ''
        ).strip()

        facility.status = request.POST.get(
            'status',
            'ACTIVE'
        )

        facility.save()

        return redirect('facility_list')

    context = {
    'facility': facility,
    'facility_types': Facility.FACILITY_TYPES,
    'status_choices': Facility.STATUS_CHOICES,
    'floor_choices': Facility.FLOOR_CHOICES,
}

    return render(
        request,
        'facilities/facility_form.html',
        context
    )

@login_required(login_url='login')
def facility_delete(request, pk):
    facility = get_object_or_404(
        Facility,
        pk=pk
    )

    if request.method == 'POST':
        facility.delete()
        return redirect('facility_list')

    return render(
        request,
        'facilities/facility_confirm_delete.html',
        {
            'facility': facility,
        }
    )

@login_required(login_url='login')
def facility_detail(request, pk):
    facility = get_object_or_404(
        Facility,
        pk=pk
    )

    assets = facility.assets.select_related(
        'category'
    ).order_by(
        'asset_code'
    )

    return render(
        request,
        'facilities/facility_detail.html',
        {
            'facility': facility,
            'assets': assets,
        }
    )

@login_required(login_url='login')
def facility_report(request):

    facilities = Facility.objects.all()

    search = request.GET.get('search', '').strip()
    facility_type = request.GET.get('facility_type', '').strip()
    building = request.GET.get('building', '').strip()
    floor = request.GET.get('floor', '').strip()
    status = request.GET.get('status', '').strip()

    if search:
        facilities = facilities.filter(
            name__icontains=search
        ) | facilities.filter(
            code__icontains=search
        ) | facilities.filter(
            building__icontains=search
        ) | facilities.filter(
            room_number__icontains=search
        ) | facilities.filter(
            responsible_person__icontains=search
        )

    if facility_type:
        facilities = facilities.filter(
            facility_type=facility_type
        )

    if building:
        facilities = facilities.filter(
            building__icontains=building
        )

    if floor:
        facilities = facilities.filter(
            floor=floor
        )

    if status:
        facilities = facilities.filter(
            status=status
        )

    buildings = (
        Facility.objects
        .exclude(building='')
        .values_list('building', flat=True)
        .distinct()
        .order_by('building')
    )

    context = {
        'facilities': facilities,
        'facility_count': facilities.count(),
        'facility_types': Facility.FACILITY_TYPES,
        'floor_choices': Facility.FLOOR_CHOICES,
        'status_choices': Facility.STATUS_CHOICES,
        'buildings': buildings,

        'search': search,
        'facility_type': facility_type,
        'building': building,
        'floor': floor,
        'status': status,
    }

    return render(
        request,
        'facilities/facility_report.html',
        context
    )

@login_required(login_url='login')
def facility_report_print(request):

    facilities = Facility.objects.all()

    search = request.GET.get('search', '').strip()
    facility_type = request.GET.get('facility_type', '').strip()
    building = request.GET.get('building', '').strip()
    floor = request.GET.get('floor', '').strip()
    status = request.GET.get('status', '').strip()

    if search:
        facilities = facilities.filter(
            name__icontains=search
        ) | facilities.filter(
            code__icontains=search
        ) | facilities.filter(
            building__icontains=search
        ) | facilities.filter(
            room_number__icontains=search
        ) | facilities.filter(
            responsible_person__icontains=search
        )

    if facility_type:
        facilities = facilities.filter(
            facility_type=facility_type
        )

    if building:
        facilities = facilities.filter(
            building__icontains=building
        )

    if floor:
        facilities = facilities.filter(
            floor=floor
        )

    if status:
        facilities = facilities.filter(
            status=status
        )

    context = {
        'facilities': facilities,
        'facility_count': facilities.count(),

        'search': search,
        'facility_type': facility_type,
        'building': building,
        'floor': floor,
        'status': status,
    }

    return render(
        request,
        'facilities/facility_report_print.html',
        context
    )

@login_required(login_url='login')
def facility_report_excel(request):

    from openpyxl import Workbook
    from openpyxl.styles import (
        Font,
        Alignment,
        PatternFill,
        Border,
        Side,
    )
    from openpyxl.utils import get_column_letter
    from openpyxl.worksheet.table import (
        Table,
        TableStyleInfo,
    )

    # =========================================================
    # دریافت اطلاعات
    # =========================================================

    facilities = Facility.objects.all()

    search = request.GET.get(
        'search',
        ''
    ).strip()

    facility_type = request.GET.get(
        'facility_type',
        ''
    ).strip()

    building = request.GET.get(
        'building',
        ''
    ).strip()

    floor = request.GET.get(
        'floor',
        ''
    ).strip()

    status = request.GET.get(
        'status',
        ''
    ).strip()

    # =========================================================
    # اعمال فیلترها
    # =========================================================

    if search:

        facilities = facilities.filter(
            name__icontains=search
        ) | facilities.filter(
            code__icontains=search
        ) | facilities.filter(
            building__icontains=search
        ) | facilities.filter(
            room_number__icontains=search
        ) | facilities.filter(
            responsible_person__icontains=search
        )

    if facility_type:

        facilities = facilities.filter(
            facility_type=facility_type
        )

    if building:

        facilities = facilities.filter(
            building__icontains=building
        )

    if floor:

        facilities = facilities.filter(
            floor=floor
        )

    if status:

        facilities = facilities.filter(
            status=status
        )

    # =========================================================
    # ایجاد Workbook
    # =========================================================

    workbook = Workbook()

    worksheet = workbook.active

    worksheet.title = 'گزارش مکان‌ها'

    # راست به چپ
    worksheet.sheet_view.rightToLeft = True

    # =========================================================
    # رنگ‌ها و Styleها
    # =========================================================

    dark_blue = '17365D'
    light_blue = 'D9EAF7'
    white = 'FFFFFF'
    border_color = 'B7B7B7'

    thin_border = Border(
        left=Side(
            style='thin',
            color=border_color
        ),
        right=Side(
            style='thin',
            color=border_color
        ),
        top=Side(
            style='thin',
            color=border_color
        ),
        bottom=Side(
            style='thin',
            color=border_color
        )
    )

    # =========================================================
    # عنوان گزارش
    # =========================================================

    worksheet.merge_cells('A1:J1')

    worksheet['A1'] = (
        'امارت اسلامی افغانستان'
    )

    worksheet['A1'].font = Font(
        bold=True,
        size=16
    )

    worksheet['A1'].alignment = Alignment(
        horizontal='center',
        vertical='center'
    )

    worksheet.merge_cells('A2:J2')

    worksheet['A2'] = (
        'وزارت تحصیلات عالی'
    )

    worksheet['A2'].font = Font(
        bold=True,
        size=14
    )

    worksheet['A2'].alignment = Alignment(
        horizontal='center',
        vertical='center'
    )

    worksheet.merge_cells('A3:J3')

    worksheet['A3'] = (
        'پوهنتون طبی چراغ'
    )

    worksheet['A3'].font = Font(
        bold=True,
        size=15
    )

    worksheet['A3'].alignment = Alignment(
        horizontal='center',
        vertical='center'
    )

    worksheet.merge_cells('A4:J4')

    worksheet['A4'] = (
        'آمریت تکنالوژی معلوماتی'
    )

    worksheet['A4'].font = Font(
        bold=True,
        size=12
    )

    worksheet['A4'].alignment = Alignment(
        horizontal='center',
        vertical='center'
    )

    worksheet.merge_cells('A5:J5')

    worksheet['A5'] = (
        'گزارش مکان‌ها'
    )

    worksheet['A5'].font = Font(
        bold=True,
        size=14
    )

    worksheet['A5'].alignment = Alignment(
        horizontal='center',
        vertical='center'
    )

    # =========================================================
    # معلومات گزارش
    # =========================================================

    worksheet['A7'] = 'تعداد مکان‌ها'

    worksheet['B7'] = facilities.count()

    worksheet['D7'] = 'تاریخ گزارش'

    worksheet['E7'] = (
        __import__('datetime').date.today()
    )

    for cell in [
        worksheet['A7'],
        worksheet['D7'],
    ]:

        cell.font = Font(
            bold=True
        )

        cell.alignment = Alignment(
            horizontal='center'
        )

    worksheet['B7'].alignment = Alignment(
        horizontal='center'
    )

    worksheet['E7'].alignment = Alignment(
        horizontal='center'
    )

    # =========================================================
    # فیلترهای اعمال‌شده
    # =========================================================

    worksheet['A8'] = 'فیلترهای گزارش'

    worksheet['A8'].font = Font(
        bold=True
    )

    filter_text = []

    if search:

        filter_text.append(
            f'جستجو: {search}'
        )

    if facility_type:

        facility_type_dict = dict(
            Facility.FACILITY_TYPES
        )

        filter_text.append(
            'نوع مکان: '
            + facility_type_dict.get(
                facility_type,
                facility_type
            )
        )

    if building:

        filter_text.append(
            f'تعمیر: {building}'
        )

    if floor:

        floor_dict = dict(
            Facility.FLOOR_CHOICES
        )

        filter_text.append(
            'طبقه: '
            + floor_dict.get(
                floor,
                floor
            )
        )

    if status:

        status_dict = dict(
            Facility.STATUS_CHOICES
        )

        filter_text.append(
            'وضعیت: '
            + status_dict.get(
                status,
                status
            )
        )

    if filter_text:

        worksheet.merge_cells(
            'B8:J8'
        )

        worksheet['B8'] = (
            ' | '.join(filter_text)
        )

    else:

        worksheet.merge_cells(
            'B8:J8'
        )

        worksheet['B8'] = (
            'بدون فیلتر - تمام مکان‌ها'
        )

    worksheet['B8'].alignment = Alignment(
        horizontal='right',
        vertical='center'
    )

    # =========================================================
    # Header جدول
    # =========================================================

    headers = [
        'شماره',
        'کد مکان',
        'نام مکان',
        'نوع مکان',
        'تعمیر',
        'طبقه',
        'شماره اتاق',
        'ظرفیت',
        'مسؤول',
        'وضعیت',
    ]

    header_row = 10

    for column, header in enumerate(
        headers,
        start=1
    ):

        cell = worksheet.cell(
            row=header_row,
            column=column
        )

        cell.value = header

        cell.font = Font(
            bold=True,
            color=white
        )

        cell.fill = PatternFill(
            fill_type='solid',
            fgColor=dark_blue
        )

        cell.alignment = Alignment(
            horizontal='center',
            vertical='center'
        )

        cell.border = thin_border

    # =========================================================
    # اطلاعات مکان‌ها
    # =========================================================

    for index, facility in enumerate(
        facilities,
        start=1
    ):

        row = header_row + index

        values = [
            index,
            facility.code,
            facility.name,
            facility.get_facility_type_display(),
            facility.building or '-',
            facility.get_floor_display(),
            facility.room_number or '-',
            facility.capacity or '-',
            facility.responsible_person or '-',
            facility.get_status_display(),
        ]

        for column, value in enumerate(
            values,
            start=1
        ):

            cell = worksheet.cell(
                row=row,
                column=column
            )

            cell.value = value

            cell.border = thin_border

            cell.alignment = Alignment(
                horizontal='center',
                vertical='center'
            )

    # =========================================================
    # جدول Excel
    # =========================================================

    last_row = (
        header_row
        + facilities.count()
    )

    if facilities.exists():

        table_reference = (
            f'A{header_row}:J{last_row}'
        )

        table = Table(
            displayName='FacilityReport',
            ref=table_reference
        )

        style = TableStyleInfo(
            name='TableStyleMedium2',
            showFirstColumn=False,
            showLastColumn=False,
            showRowStripes=True,
            showColumnStripes=False
        )

        table.tableStyleInfo = style

        worksheet.add_table(table)

    # =========================================================
    # تنظیم عرض ستون‌ها
    # =========================================================

    column_widths = {

        'A': 10,
        'B': 18,
        'C': 28,
        'D': 20,
        'E': 20,
        'F': 18,
        'G': 18,
        'H': 12,
        'I': 25,
        'J': 18,

    }

    for column, width in column_widths.items():

        worksheet.column_dimensions[
            column
        ].width = width

    # =========================================================
    # ارتفاع ردیف‌ها
    # =========================================================

    worksheet.row_dimensions[1].height = 25
    worksheet.row_dimensions[2].height = 23
    worksheet.row_dimensions[3].height = 25
    worksheet.row_dimensions[4].height = 22
    worksheet.row_dimensions[5].height = 24
    worksheet.row_dimensions[10].height = 25

    # =========================================================
    # Freeze Header
    # =========================================================

    worksheet.freeze_panes = 'A11'

    # =========================================================
    # تنظیمات چاپ
    # =========================================================

    worksheet.page_setup.orientation = (
        'landscape'
    )

    worksheet.page_setup.paperSize = (
        worksheet.PAPERSIZE_A4
    )

    worksheet.page_setup.fitToWidth = 1

    worksheet.page_setup.fitToHeight = 0

    worksheet.sheet_properties.pageSetUpPr.fitToPage = True

    worksheet.print_title_rows = '1:10'

    worksheet.print_area = (
        f'A1:J{last_row}'
    )

    # =========================================================
    # ایجاد Response
    # =========================================================

    response = HttpResponse(
        content_type=(
            'application/vnd.openxmlformats-officedocument'
            '.spreadsheetml.sheet'
        )
    )

    response[
        'Content-Disposition'
    ] = (
        'attachment; '
        'filename="IT_Facility_Report.xlsx"'
    )

    sanitize_workbook(workbook)
    workbook.save(response)

    return response