# -*- coding: utf-8 -*-

import os
import base64
import datetime

from odoo import models, fields, api, SUPERUSER_ID
from odoo.exceptions import ValidationError, AccessError


class DataExportRecord(models.Model):
    _name = 'jd.base.data.export.record'
    _description = u'数据导出记录'
    _order = 'id desc'

    company_id = fields.Many2one('res.company', string="组织")
    model_id = fields.Many2one('ir.model', string="模型", compute="_get_model_id")
    model = fields.Char(string="模型名")
    menu_id = fields.Many2one('ir.ui.menu', string="菜单", compute="_get_menu", store=True)
    action_id = fields.Many2one('ir.actions.actions', string="动作")
    export_id = fields.Many2one('ir.exports', string="导出模板")
    export_domain = fields.Char(string="查询domain")
    export_start = fields.Datetime(string="导出时间")
    export_end = fields.Datetime(string="结束时间")
    export_minutes = fields.Float(string="导出时长(分)", compute='_get_export_minutes', store=True, default=0)
    
    file = fields.Binary(string=u'文件', store=True, attachment=True)
    image = fields.Binary(string=u'文件缩略图', compute='_get_image')
    file_name = fields.Char(string=u'文件名称', default='/', readonly=True)
    file_size = fields.Float(string=u'大小(KB)', default=0, compute='_get_file_size', store=True)
    download_count = fields.Integer(string="下载次数", default=0)
    rows = fields.Integer(string="行数")
    columns = fields.Integer(string="列数")

    note = fields.Char(string=u'备注')

    @api.multi
    @api.depends('file')
    def _get_image(self):
        """
        不同文件类型使用不同图标 TODO: 支持更多类型和图标
        :return:
        """
        for item in self:
            if item.file:
                abs_path = os.path.abspath('.')
                img_base_path = 'base/app_base/jd_base/static/src/img/'
                file_name = item.file_name
                if file_name.endswith('.xls') or file_name.endswith('.xlsx'):
                    img_path = os.path.join(abs_path, img_base_path, 'icon-xls-m.png')
                elif file_name.endswith('.doc') or file_name.endswith('.docx'):
                    img_path = os.path.join(abs_path, img_base_path, 'icon-doc-m.png')
                elif file_name.endswith('.ppt') or file_name.endswith('.pptx'):
                    img_path = os.path.join(abs_path, img_base_path, 'icon-ppt-m.png')
                elif file_name.endswith('.pdf'):
                    img_path = os.path.join(abs_path, img_base_path, 'icon-pdf-m.png')
                else:
                    img_path = os.path.join(abs_path, img_base_path, 'icon-default-m.png')
                with open(img_path, 'rb') as f:
                    item.image = base64.b64encode(f.read())

    @api.multi
    @api.depends('file')
    def _get_file_size(self):
        for item in self:
            if item.file:
                bin_data = item.file and item.file.decode('base64') or ''
                item.file_size = len(bin_data) / 1024.0
    
    @api.multi
    @api.depends('export_start', 'export_end')
    def _get_export_minutes(self):
        for item in self:
            if item.export_start and item.export_end:
                export_start = datetime.datetime.strptime(item.export_start, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(hours=8)
                export_end = datetime.datetime.strptime(item.export_end, '%Y-%m-%d %H:%M:%S') + datetime.timedelta(hours=8)
                item.export_minutes = (export_end - export_start).seconds % 3600 / 60.0
    
    @api.multi
    @api.depends('model')
    def _get_model_id(self):
        for item in self:
            if item.model:
                model_rec = self.env['ir.model'].search([('model', '=', item.model)], limit=1)
                if model_rec:
                    item.model_id = model_rec.id
                else:
                    item.model_id = None
    
    @api.multi
    @api.depends('action_id')
    def _get_menu(self):
        for item in self:
            if item.action_id:
                action = item.action_id.type + ',' + str(item.action_id.id)
                menu_rec = self.env['ir.ui.menu'].search([('action', '=', action)], limit=1)
                if menu_rec:
                    item.menu_id = menu_rec.id
                else:
                    item.menu_id = None
    
    @api.multi
    def download(self):
        for item in self:
            if self.env.user.id not in (item.create_uid.id, SUPERUSER_ID):
                raise ValidationError("只允许下载本人导出的文件")
            item.download_count += 1
            url = '/web/content?model=%s&field=file&id=%s&download=true&filename_field=file_name' % (self._name, item.id)
            return {
                'type': 'ir.actions.act_url',
                'url': url,
                # 'target': 'new',
            }

    @api.model
    def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
        """
        Performs a ``search()`` followed by a ``read()``.

        :param domain: Search domain, see ``args`` parameter in ``search()``. Defaults to an empty domain that will match all records.
        :param fields: List of fields to read, see ``fields`` parameter in ``read()``. Defaults to all fields.
        :param offset: Number of records to skip, see ``offset`` parameter in ``search()``. Defaults to 0.
        :param limit: Maximum number of records to return, see ``limit`` parameter in ``search()``. Defaults to no limit.
        :param order: Columns to sort result, see ``order`` parameter in ``search()``. Defaults to no sort.
        :return: List of dictionaries containing the asked fields.
        :rtype: List of dictionaries.

        """
        user = self.env.user
        # 非系统设置权限组的用户只能看到本人创建和所有下级组织的记录
        if user.has_group('base.group_system'):
            default_domain = domain or []
        else:
            default_domain = ['&', ('create_uid', '=', user.id), '|','|','|',
                ('company_id','=',False), ('company_id','=',user.branch_company_id.id),
                ('company_id','child_of',[user.company_id.id]), ('company_id','management_child_of',[user.company_id.id])]
            if domain:
                default_domain.extend(domain)
        records = self.search(default_domain, offset=offset, limit=limit, order=order)

        if not records:
            return []

        if fields and fields == ['id']:
            # shortcut read if we only want the ids
            return [{'id': record.id} for record in records]

        # read() ignores active_test, but it would forward it to any downstream search call
        # (e.g. for x2m or function fields), and this is not the desired behavior, the flag
        # was presumably only meant for the main search().
        # TODO: Move this to read() directly?
        if 'active_test' in self._context:
            context = dict(self._context)
            del context['active_test']
            records = records.with_context(context)

        result = records.read(fields)
        if len(result) <= 1:
            return result

        # reorder read
        index = {vals['id']: vals for vals in result}
        return [index[record.id] for record in records if record.id in index]
