# -*- coding: utf-8; -*-
################################################################################
#
#  Rattail -- Retail Software Framework
#  Copyright © 2010-2024 Lance Edgar
#
#  This file is part of Rattail.
#
#  Rattail is free software: you can redistribute it and/or modify it under the
#  terms of the GNU General Public License as published by the Free Software
#  Foundation, either version 3 of the License, or (at your option) any later
#  version.
#
#  Rattail 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 General Public License for more
#  details.
#
#  You should have received a copy of the GNU General Public License along with
#  Rattail.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Vendor catalog parser for United Natural Foods (UNFI)
"""

import re
import datetime
import decimal

import xlrd

from rattail.vendors.catalogs import CatalogParser
from rattail.csvutil import UnicodeDictReader


class UNFICatalogParser(CatalogParser):
    """
    Vendor catalog parser for UNFI, version 1.
    """
    key = 'rattail.contrib.unfi'
    display = "United Natural Foods (UNFI), Excel v1"
    vendor_key = 'unfi'

    effective_date_pattern = re.compile(r'effective from (\d{2}/\d{2}/\d{4})-')
    code_pattern = re.compile(r'^\d{6}-\d$')
    upc_pattern = re.compile(r'^\d-\d{5}-\d{5}-\d$')

    def open_sheet(self, path):
        book = xlrd.open_workbook(path)
        return book.sheet_by_index(0)

    def parse_effective_date(self, path):
        sheet = self.open_sheet(path)
        text = sheet.cell_value(0, 0)
        match = self.effective_date_pattern.search(text)
        if match:
            return datetime.datetime.strptime(match.group(1), '%m/%d/%Y').date()

    def parse_rows(self, path, progress=None):
        sheet = self.open_sheet(path)
        for r in range(sheet.nrows):

            # Use the code to determine if the row is valid.
            code = sheet.cell_value(r, 0)
            if not self.code_pattern.match(code):
                continue

            # Warn if UPC is not valid.
            upc = sheet.cell_value(r, 1)
            if self.upc_pattern.match(upc):
                upc = self.app.make_gpc(upc.replace('-', ''))
            else:
                log.warning("invalid upc at row {0}: {1}".format(r + 1, upc))
                upc = None

            row = self.make_row()
            row.upc = upc
            row.vendor_code = code.replace('-', '')
            row.brand_name = sheet.cell_value(r, 2)
            row.description = sheet.cell_value(r, 3)
            row.size = sheet.cell_value(r, 5)
            row.case_size = int(sheet.cell_value(r, 4))
            row.case_cost = decimal.Decimal(str(sheet.cell_value(r, 8)))
            row.unit_cost = decimal.Decimal(str(sheet.cell_value(r, 9)))
            yield row


class UNFICatalogParser2(UNFICatalogParser):
    """
    Vendor catalog parser for UNFI, version 2.
    """
    key = 'rattail.contrib.unfi.2'
    display = "United Natural Foods (UNFI), Excel v2"

    def parse_rows(self, path, progress=None):
        sheet = self.open_sheet(path)
        for r in range(sheet.nrows):

            # Use the code to determine if the row is valid.
            code = sheet.cell_value(r, 0)
            if not self.code_pattern.match(code):
                continue

            # Warn if UPC is not valid.
            upc = sheet.cell_value(r, 1)
            if self.upc_pattern.match(upc):
                upc = self.app.make_gpc(upc.replace('-', ''))
            else:
                log.warning("invalid upc at row {0}: {1}".format(r + 1, upc))
                upc = None

            row = self.make_row()
            row.upc = upc
            row.vendor_code = code.replace('-', '')
            row.brand_name = sheet.cell_value(r, 2)
            row.description = sheet.cell_value(r, 4)
            row.size = sheet.cell_value(r, 7)
            row.case_size = int(sheet.cell_value(r, 6))
            row.case_cost = decimal.Decimal(str(sheet.cell_value(r, 10)))
            row.unit_cost = decimal.Decimal(str(sheet.cell_value(r, 11)))
            yield row


class UNFITabSeparatedCatalogParser(CatalogParser):
    """
    Vendor catalog parser for UNFI, tab-separated values format
    """
    key = 'rattail.contrib.unfi.tsv'
    display = "United Natural Foods (UNFI), tab-separated"
    vendor_key = 'unfi'

    def parse_rows(self, csv_path, progress=None):
        csv_file = open(csv_path, 'rt', encoding='latin_1')
        # nb. skip first "message" line
        next(csv_file)
        reader = UnicodeDictReader(csv_file, dialect='excel-tab')

        for csvrow in reader:
            row = self.make_row()

            row.item_entry = csvrow['UPRD']
            row.item_id = csvrow['UPCC']
            row.upc = self.app.make_gpc(csvrow['UPCC'])
            row.vendor_code = csvrow['UPRD']
            row.brand_name = csvrow['BRND']
            row.description = csvrow['DESC']
            row.size = csvrow['SIZE']
            row.case_size = self.decimal(csvrow['PACK'])
            row.case_cost = int(csvrow['CAVD']) / decimal.Decimal('100.00')
            row.unit_cost = row.case_cost / row.case_size

            yield row

        csv_file.close()
