import csv

import pandas

import django
from django.conf import settings
from django.contrib import admin
from django.http import HttpResponse, HttpResponseForbidden
from builtins import str as text


def export_as_csv(admin_model, request, queryset):
    """
    Generic csv export admin action.
    based on http://djangosnippets.org/snippets/1697/
    """
    # everyone has perms to export as csv unless explicitly defined
    if getattr(settings, 'DJANGO_EXPORTS_REQUIRE_PERM', None):
        admin_opts = admin_model.opts
        codename = '%s_%s' % ('csv', admin_opts.object_name.lower())
        has_csv_permission = request.user.has_perm("%s.%s" % (admin_opts.app_label, codename))
    else:
        has_csv_permission = admin_model.has_csv_permission(request) \
            if (hasattr(admin_model, 'has_csv_permission') and callable(getattr(admin_model, 'has_csv_permission'))) \
            else True
    if has_csv_permission:
        opts = admin_model.model._meta
        if getattr(admin_model, 'csv_fields', None):
            field_names = admin_model.csv_fields
        else:
            field_names = [field.name for field in opts.fields]
            field_names.sort()

        if django.VERSION[0] == 1 and django.VERSION[1] <= 5:
            response = HttpResponse(mimetype='text/csv')
        else:
            response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=%s.csv' % text(opts).replace('.', '_')

        queryset = queryset.values_list(*field_names)
        pandas.DataFrame(list(queryset), columns=field_names).to_csv(response, index=False, encoding='utf-8')
        return response
    return HttpResponseForbidden()
export_as_csv.short_description = "Export selected objects as csv file"


class CSVExportAdmin(admin.ModelAdmin):
    def get_actions(self, request):
        actions = super(CSVExportAdmin, self).get_actions(request)
        if self.has_csv_permission(request):
            actions['export_as_csv'] = (export_as_csv, 'export_as_csv', "Export selected objects as csv file")
        return actions

    def has_csv_permission(self, request, obj=None):
        """
        Returns True if the given request has permission to add an object.
        Can be overridden by the user in subclasses. By default, we assume
        all staff users can use this action unless `DJANGO_EXPORTS_REQUIRE_PERM`
        is set to True in your django settings.
        """
        if getattr(settings, 'DJANGO_EXPORTS_REQUIRE_PERM', None):
            opts = self.opts
            codename = '%s_%s' % ('csv', opts.object_name.lower())
            return request.user.has_perm("%s.%s" % (opts.app_label, codename))
        return True


if getattr(settings, 'DJANGO_CSV_GLOBAL_EXPORTS_ENABLED', True):
    admin.site.add_action(export_as_csv)