# barbacompta - invoicing for dummies
# Copyright (C) 2010-2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import logging
import os.path

from django import http
from django.conf import settings
from django.contrib import messages
from django.contrib.admin.models import LogEntry
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404, redirect

from eo_gestion.chorus.chorus import push_to_chorus

from .models import Contrat, Facture

logger = logging.getLogger(__name__)


def facture(request, facture):
    return http.Response(
        get_object_or_404(Facture, id=facture).html(base_uri=request.build_absolute_uri('/'))
    )


def facture_pdf(request, facture_id):
    facture = get_object_or_404(Facture, id=facture_id)
    if 'facturx' in request.GET:
        pdf = facture.facturx_pdf(base_uri=request.build_absolute_uri('/'))
    else:
        pdf = facture.pdf(base_uri=request.build_absolute_uri('/'))
    if hasattr(settings, 'FACTURE_DIR'):
        filename = os.path.join(
            settings.FACTURE_DIR,
            '%s-%s.pdf' % (facture.code(), facture.contrat.client.nom.encode('utf8')),
        )
        with open(filename, 'wb') as fd:
            fd.write(pdf)
    return http.HttpResponse(pdf, content_type='application/pdf')


def api_references(request):
    data = []
    qs = (
        Contrat.objects.exclude(public_description='')
        .exclude(client__picture__isnull=True)
        .exclude(client__picture='')
        .prefetch_related('tags')
    )
    if 'tags' in request.GET:
        qs = qs.filter(tags__name__in=request.GET.getlist('tags'))
    for contract in qs:
        data.append(
            {
                'title': contract.intitule,
                'description': contract.public_description,
                'client': contract.client.nom,
                'logo': request.build_absolute_uri(contract.client.picture.url),
                'url': contract.url,
                'tags': [tag.name for tag in contract.tags.all()],
            }
        )
        if contract.image:
            data[-1]['image'] = request.build_absolute_uri(contract.image.url)
    return http.JsonResponse({'data': data})


def send_to_chorus(request, facture_id):
    facture = get_object_or_404(Facture, id=facture_id)

    if facture.client.chorus_structure and not facture.proforma:
        logger.info('sending invoice %s to ChorusPro', facture)
        response = push_to_chorus(
            facture.facturx_pdf(base_uri=request.build_absolute_uri('/')), facture.code() + '.pdf'
        )

        description = ''
        if 'numeroFluxDepot' in response:
            msg = f'Facture {facture.code()} envoyée à ChorusPro'
            for key, value in response.items():
                description += f' | {key} - {value}'
        else:
            msg = f'Échec d\'envoi de la facture {facture.code()} à ChorusPro'

        msg += description
        LogEntry.objects.create(
            user=request.user,
            content_type=ContentType.objects.get_for_model(facture),
            object_id=facture_id,
            object_repr=str(facture),
            action_flag=0,
            change_message=msg,
        )

        if 'numeroFluxDepot' in response:
            logger.info('sent invoice %s to ChorusPro, response: %s', facture, description)
            messages.info(request, msg)
        else:
            logger.warning('failed to send invoice %s to ChorusPro, response: %s', facture, description)
            messages.error(request, msg)
    return redirect('admin:eo_facture_facture_change', facture_id)


def cancel(request, facture_id):
    facture = get_object_or_404(Facture, id=facture_id)
    facture_avoir = facture.cancel(request.user)
    return redirect('admin:eo_facture_facture_change', facture_avoir.id)
