# coding=utf-8
import os
import traceback
import json

from django.conf import settings
from django.utils import timezone
from django.db.models import ProtectedError
from django.views.decorators.csrf import csrf_exempt
from django.db import transaction, IntegrityError
from django.db.models import Q

from apps.office.filters import NoticeFilter
from apps.office.models import Notice, NoticeReply, NoticeBrowseRecord, NoticeAttachment

from apps.account.decorators import token_required, permission_required
from apps.base import Formater
from apps.foundation.models import BizLog
from apps.office.serializers import NoticeSerializer, NoticeBrowseRecordSerializer, NoticeReplySerializer

from libs.http import JSONResponse, JSONError, DataGridJSONResponse
from libs import utils
from apps.exceptions import CustomError


@permission_required('office.view_notice')
def notice_list(request):
    f = NoticeFilter(request.GET, queryset=Notice.objects.filter())
    rows, total = utils.get_page_data(request, f.qs)
    serializer = NoticeSerializer(rows, many=True)
    return DataGridJSONResponse(serializer.data, total)


@csrf_exempt
@permission_required('office.add_notice')
def notice_save(request):
    id = request.GET.get('id')
    data = json.loads(request.body)
    try:
        with transaction.atomic():
            data['dendline'] += ' 00:00:00'
            serializer = NoticeSerializer.factory(request.user, data, id)
            serializer = serializer.validSave()
            if id:
                item_data = {'notice': serializer.id}
                replys = NoticeReply.getByNotice(id)
                reply_ids = replys.values_list('id')
                for reply_id in reply_ids:
                    reply_serializer = NoticeReplySerializer.factory(request.user, item_data, reply_id[0])
                    reply_serializer.validSave()

                browserecords = NoticeBrowseRecord.getByNotice(id)
                browserecord_ids = browserecords.values_list('id')
                for browserecord_id in browserecord_ids:
                    browserecord_serializer = NoticeBrowseRecordSerializer.factory(request.user, item_data, browserecord_id[0])
                    browserecord_serializer.validSave()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse()

@permission_required('office.delete_notice')
def notice_delete(request):
    id = int(request.GET.get('id'))

    try:
        with transaction.atomic():
            notice = Notice.getById(id)
            BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除公告[%s]，id=%d" % (notice.title, notice.id))
            notice.delete()
            browserecords = NoticeBrowseRecord.getByNotice(id)
            for browserecord in browserecords:
                BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除公告回复id=%d" % (browserecord.id))
                browserecord.delete()
            replys = NoticeReply.getByNotice(id)
            for reply in replys:
                BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除公告回复id=%d" % (reply.id))
                reply.delete()
            attachments = NoticeAttachment.getByNotice(id)
            for attachment in attachments:
                BizLog.objects.addnew(request.user, BizLog.DELETE, u"删除公告回复id=%d" % (attachment.id))
                attachment.delete()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except ProtectedError:
        return JSONError(u'该公告已被使用，禁止删除！')
    except IntegrityError:
        return JSONError(u'该公告已被使用，禁止删除！')
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'删除失败！')

    return JSONResponse({})

@token_required
@permission_required('office.view_notice')
def notice_detail(request):
    id = request.GET.get('id')
    if not id:
        return JSONResponse()
    instance = Notice.getById(id)

    try:
        with transaction.atomic():
            hits = instance.hits
            new_hits = int(hits) + 1
            instance.hits = new_hits
            instance.save()
            item_data = {'notice': instance.id}
            browserecord_serializer = NoticeBrowseRecordSerializer.factory(request.user, item_data)
            browserecord_serializer.validSave()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'查看失败！')

    if instance.priority == Notice.NORMAL:
        priority = u'普通'
    else:
        priority = u'紧急'
    main_data = {
        'id': id,
        'title': instance.title,
        'priority': instance.priority,
        'priority_text': priority,
        'department_name': instance.department.name,
        'hits': instance.hits,
        'content': instance.content,
        'create_user_text': instance.create_user.name,
        'create_time': Formater.formatStrTime(instance.create_time),
        'dendline': Formater.formatStrDate(instance.dendline)
    }

    data = {
        'main_data': main_data,
        'items_data': []
    }
    rows = NoticeReply.getByNotice(id)
    for row in rows:
        item_data = {
            'id': row.id,
            'content': row.content,
            'create_user_text': row.create_user.name,
            'create_time': Formater.formatStrTime(row.create_time)
        }
        data['items_data'].append(item_data)

    return JSONResponse(data)

@token_required
def notice_answer(request):
    id = request.GET.get('id')
    data = json.loads(request.body)
    try:
        with transaction.atomic():
            data['notice'] = id
            reply_serializer = NoticeReplySerializer.factory(request.user, data)
            reply_serializer.validSave()
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception, e:
        traceback.print_exc()
        return JSONError(u'保存失败！')
    return JSONResponse()


@token_required
@permission_required('office.view_browserecord')
def notice_browserecord(request):
    id = request.GET.get('id')
    if not id:
        return JSONResponse()
    instance = Notice.getById(id)
    if instance.priority == Notice.NORMAL:
        priority = u'普通'
    else:
        priority = u'紧急'
    main_data = {
        'id': id,
        'title': instance.title,
        'priority': instance.priority,
        'priority_text': priority,
        'department_name': instance.department.name,
        'hits': Formater.formatCountShow(instance.hits),
        'content': instance.content,
        'create_time': Formater.formatStrTime(instance.create_time),
        'dendline': Formater.formatStrDate(instance.dendline)
    }

    data = {
        'main_data': main_data,
        'items_data': []
    }
    rows = NoticeBrowseRecord.getByNotice(id)
    for row in rows:
        item_data = {
            'id': row.id,
            'department': row.department.name,
            'browse_user_name': row.browse_user.name,
            'create_time': Formater.formatStrTime(row.create_time)
        }
        data['items_data'].append(item_data)

    return JSONResponse(data)


@token_required
def notice_upload_files(request):
    ids = request.POST.get('ids')
    files = request.FILES.getlist('file')
    try:
        with transaction.atomic():
            ids = str(ids).split(',')
            from models import path_and_rename
            for id in ids:
                notice = Notice.objects.filter(id=id).first()
                if not notice:
                    raise CustomError(u'未找到公告')
                for file in files:
                    filename = "%s%d-%s.%s" % (
                        path_and_rename.path,
                        notice.id,
                        timezone.now().strftime('%Y%m%d%H%M%S%f'),
                        file.name.split('.')[-1]
                    )
                    filename = filename.lower()
                    full_filename = "%s/%s" % (settings.MEDIA_ROOT, filename)
                    with open(full_filename, 'wb+') as destination:
                        for chunk in file.chunks():
                            destination.write(chunk)

                    NoticeAttachment.objects.create(notice=notice, file=filename)
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except Exception,e:
        traceback.print_exc()
        return JSONError(u'上传失败')
    return JSONResponse({})

@token_required
def notice_files(request):
    id = request.GET.get('id')
    rows = NoticeAttachment.objects.filter(notice_id=int(id))
    rows, total = utils.get_page_data(request, rows)
    data = []
    for row in rows:
        item = {
            'id': row.id,
            'notice_id': row.notice.id,
            'files': unicode(row.file),
            'files_name': str(row.file).split('/')[-1],
            'files_url': row.file,
        }
        data.append(item)
    return DataGridJSONResponse(data, total)

@token_required
def notice_del_files(request):
    id = request.GET.get('id')

    try:
        with transaction.atomic():
            file = NoticeAttachment.objects.filter(id=int(id)).first()
            file.delete()
            try:
                os.remove("%s/%s" % (settings.MEDIA_ROOT, file.file))
            except:
                pass
    except CustomError, e:
        return JSONError(e.get_error_msg())
    except:
        traceback.print_exc()
        return JSONError(u"删除失败")
    return JSONResponse({})

@csrf_exempt
@permission_required('office.view_notice')
def touch_notice_list(request):

    children = request.user.getSubDepartmentIds()
    children.append(request.user.department.id)
    rows = Notice.objects.filter(dendline__gte=timezone.now(), department__in=children)
    browsed_ids = NoticeBrowseRecord.objects.filter(browse_user_id=request.user).values_list('notice_id', flat=True)
    not_notices = rows.filter(~Q(id__in=browsed_ids))

    ids = []
    for notice in not_notices:
        ids.append(notice.id)
    rows, total = utils.get_page_data(request, rows)

    data = []
    for row in rows:
        item = {'title': row.title, 'id': row.id, 'create_time': Formater.formatStrTime(row.create_time), 'status_text': u'已读',
                'status': 2}
        if row.id in ids:
            item['status_text'] = u'未读'
            item['status'] = 1
        data.append(item)

    return  DataGridJSONResponse(data, total)