# coding: utf-8
from __future__ import absolute_import, print_function, unicode_literals

import csv
import datetime

from django.core.management import BaseCommand

from api.models.seo import SeoDigest, SeoCategory
"""
        csv结构
        id          标题         关键词         描述          seo项目ID         内容
                    (必填)       (必填)                      (必填)            (必填)
"""

# column_names -> ('属性名', 是否为必填项')
column_names = [('id', False), (u'标题', True), (u'关键词', True),
                (u'描述', False), (u'seo项目ID', True), (u'内容', True)]


def decode_record(record):
    return [column.decode('utf-8') for column in record]


def verify_first_line(record):
    incorrect_columns = []
    decoded_record = decode_record(record)

    for index, column in enumerate(decoded_record):
        if column != column_names[index][0]:
            incorrect_columns.append(column)

    if incorrect_columns:
        print(u'数据源字段错误!')
        columns_str = ', '.join(incorrect_columns)
        print(u'错误字段:%s' % columns_str)
        return False
    else:
        return True


def filter_record(record):
    record_id = record[0]
    blank_columns = []
    for index, column in enumerate(record):
        if column_names[index][1] and not column:
            blank_columns.append(column_names[index][0])

    if blank_columns:
        print("id: %s columns %s won't be null" % (record_id, ', '.join(blank_columns)))
        return False

    else:
        return True


class Command(BaseCommand):
    errors = []

    def add_arguments(self, parser):
        parser.add_argument('path', nargs='+', type=str)

    def import_csv_data(self, file_path):
        """
        :param file_path:
        :return:
        """
        records = []
        with open(file_path, 'rb') as fd:
            csv_data = csv.reader(fd)
            first_record = csv_data.next()
            verified = verify_first_line(first_record)
            if not verified:
                raise ValueError

            for record in csv_data:
                decoded_record = decode_record(record)
                verified = filter_record(decoded_record)
                if verified:
                    records.append(decoded_record)

        return records

    def insert_data(self, records):
        for record in records:
            try:
                category_id = int(record[4])
                category = SeoCategory.objects.get(pk=category_id)
            except SeoCategory.DoesNotExist:
                self.errors.append('failed to import No.%s data' % record[0])
                continue

            kwargs = {
                'title': record[1],
                'keywords': record[2],
                'description': record[3],
                'seo_category': category,
                'content': record[5],
                'online_time': datetime.datetime.now(),
                'is_online': True,
            }
            article, created = SeoDigest.objects.get_or_create(**kwargs)
            if not created:
                self.errors.append('failed to insert No.%s data' % record[0])

    def handle(self, *args, **options):
        try:
            file_path = options['path'][0]
        except:
            print('csv file path error')
            return
        try:
            import_records = self.import_csv_data(file_path)
        except:
            print('ERROR: failed to import csv data')
            return

        if import_records:
            print('records count: %s' % len(import_records))
            print('start inserting...')
            self.insert_data(import_records)
        else:
            print('No new data!')

        if self.errors:
            for error in self.errors:
                print(error)
