# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, Id
from trytond.model import (ModelSQL, ModelView, sort)
from trytond.tools import is_full_text, lstrip_wildcard
from trytond.transaction import Transaction, inactive_records
from decimal import getcontext, Decimal, ROUND_HALF_UP
from sql.aggregate import Count, Max, Min, Sum, Avg, BoolOr
from sql.conditionals import Case
from sql import Column, Literal
from sql.functions import CurrentTimestamp, DateTrunc
from trytond.wizard import Wizard, StateView, StateTransition, StateAction, Button
from itertools import chain, groupby
from operator import itemgetter
import datetime
import logging

logger = logging.getLogger(__name__)

class CreateLCStart(ModelView):
    'Create LC Start'
    __name__ = 'create.lc.start'
    base_amount = fields.Numeric(
        'LC amount',
        digits=(16, 2),
        readonly=True,
        help="LC amount"
    )
    percentage = fields.Numeric(
        'Percentage',
        digits=(16, 2),
        readonly=False,
        help="Percentage of the amount for the LC"
    )
    amount = fields.Numeric(
        'Amount',
        digits=(16, 2),
        required=True,
        help="LC amount, calculated but editable."
    )

    @fields.depends('percentage','base_amount')
    def on_change_with_amount(self):
        if self.percentage and self.percentage > 0:
            return round(self.base_amount * self.percentage / 100,2)

class LCMessage(ModelView):
    'LC Created Message'
    __name__ = 'create.lc.message'

    message = fields.Char('Message', readonly=True)
    lc_in = fields.Many2One('lc.letter.incoming', 'LC in')
    lc_out = fields.Many2One('lc.letter.outgoing', 'LC out')

class CreateLCWizard(Wizard):
    'Create LC Wizard'
    __name__ = 'create.lc'

    start = StateView(
        'create.lc.start',
        'purchase_trade.create_lc_start_form',
        [
            Button('Cancel', 'end', 'tryton-cancel'),
            Button('Create', 'create_lc', 'tryton-ok', default=True),
        ]
    )
    create_lc = StateTransition()
    lc_id = None
    message_in = StateView(
        'create.lc.message',
        'purchase_trade.create_lc_message_form',
        [
            Button('OK', 'end', 'tryton-ok'),
            Button('See LC', 'see_lc_in', 'tryton-go-next'),
        ]
    )
    message_out = StateView(
        'create.lc.message',
        'purchase_trade.create_lc_message_form',
        [
            Button('OK', 'end', 'tryton-ok'),
            Button('See LC', 'see_lc_out', 'tryton-go-next'),
        ]
    )
    see_lc_in = StateAction('purchase_trade.act_lc_in_form')
    see_lc_out = StateAction('purchase_trade.act_lc_out_form')

    def default_start(self, fields):
        context = Transaction().context
        active_model = context.get('active_model')
        ids = context.get('active_ids')
        percentage = Decimal(0)
        amount = Decimal(0)
        base_amount = Decimal(0)
        for i in ids:
            if active_model == 'sale.sale':
                Sale = Pool().get('sale.sale')
                sale = Sale(i)
                if sale.lines:
                    line = sale.lines[0]
                    base_amount = line.amount
                    amount = base_amount * percentage / Decimal(100)
            else:
                Purchase = Pool().get('purchase.purchase')
                purchase = Purchase(i)
                if purchase.lines:
                    line = purchase.lines[0]
                    base_amount = line.amount
                    amount = base_amount * percentage / Decimal(100)
        
        return {
            'percentage': percentage,
            'base_amount': base_amount,
            'amount': amount,
            }

    def transition_create_lc(self):
        pool = Pool()
        context = Transaction().context
        active_model = context.get('active_model')
        id = Transaction().context['active_id']
        if active_model == 'sale.sale':
            LCIncoming = pool.get('lc.letter.incoming')
            amount = self.start.amount
            vals = LCIncoming.create_from_sale(id)
            vals['amount'] = amount
            lc = LCIncoming.create([vals])[0]
            DocReq = Pool().get('contract.document.type')
            docs = DocReq.search(['sale','=',id])
            if docs:
                for d in docs:
                    d.lc_in = lc.id
                DocReq.save(docs)
            self.message_in.lc_in = lc
            return 'message_in'
        else:
            LCOutgoing = pool.get('lc.letter.outgoing')
            amount = self.start.amount
            vals = LCOutgoing.create_from_purchase(id)
            vals['amount'] = amount
            lc = LCOutgoing.create([vals])[0]
            DocReq = Pool().get('contract.document.type')
            docs = DocReq.search(['purchase','=',id])
            if docs:
                for d in docs:
                    d.lc_out = lc.id
                DocReq.save(docs)
            self.message_out.lc_out = lc
            return 'message_out'

    def default_message_in(self, fields):
        return {
            'message': 'The LC has been successfully created.',
        }
    
    def default_message_out(self, fields):
        return {
            'message': 'The LC has been successfully created.',
        }

    def do_see_lc_in(self, action):
        action['views'].reverse()  # pour ouvrir en form directement
        return action, {'res_id':self.message_in.lc_in.id}
    
    def do_see_lc_out(self, action):
        action['views'].reverse()  # pour ouvrir en form directement
        return action, {'res_id':self.message_out.lc_out.id}

class LCMT700(ModelSQL, ModelView):
    'Letter of Credit MT700'
    __name__ = 'lc.mt700'

    name = fields.Char("Name")
    lc = fields.Text("Lc corpus")
    format_lc = fields.Boolean("Format LC")
    f_27 = fields.Char('27: Sequence of Total')
    f_40A = fields.Char('40A: Form of Documentary Credit')
    f_20 = fields.Char('20: Documentary Credit Number')
    f_23 = fields.Char('23: Reference to Pre-Advice')
    f_31C = fields.Date('31C: Date of Issue')
    f_40E = fields.Char('40E: Applicable Rules')
    f_31D = fields.Char('31D: Date and Place of Expiry')
    f_51a = fields.Char('51a: Applicant Bank')
    f_50 = fields.Char('50: Applicant')
    f_59 = fields.Char('59: Beneficiary')
    f_32B = fields.Numeric('32B: Currency Code, Amount')
    f_39A = fields.Char('39A: Percentage Credit Amount Tolerance')
    f_39C = fields.Char('39C: Additional Amounts Covered')
    f_41a = fields.Char('41a: Available With ... By ...')
    f_42C = fields.Char('42C: Drafts at ...')
    f_42a = fields.Char('42a: Drawee')
    f_42M = fields.Char('42M: Mixed Payment Details')
    f_42P = fields.Char('42P: Negotiation/Deferred Payment Details')
    f_43P = fields.Char('43P: Partial Shipments')
    f_43T = fields.Char('43T: Transshipment')
    f_44A = fields.Char('44A: Place of Taking in Charge/Dispatch from .../ Place of Receipt')
    f_44E = fields.Char('44E: Port of Loading/Airport of Departure')
    f_44F = fields.Char('44F: Port of Discharge/Airport of Destination')
    f_44B = fields.Char('44B: Place of Final Destination/For Transportation to.../ Place of Delivery')
    f_44C = fields.Date('44C: Latest Date of Shipment')
    f_44D = fields.Char('44D: Shipment Period')
    f_45A = fields.Text('45A: Description of Goods and/or Services')
    f_46A = fields.Text('46A: Documents Required')
    f_47A = fields.Text('47A: Additional Conditions')
    f_71B = fields.Text('71B: Charges')
    f_48 = fields.Char('48: Period for Presentation')
    f_49 = fields.Char('49: Confirmation Instructions')
    f_53a = fields.Char('53a: Reimbursing Bank')
    f_78 = fields.Text('78: Instructions to the Paying/Accepting/Negotiating Bank')
    f_57a = fields.Char('57a: Advise Through Bank')
    f_72 = fields.Text('72: Sender to Receiver Information')

    def get_formatted_lc(self):
        lc_fields = [
            '27', '40A', '20', '23', '31C', '40E', '31D', '51a', '50', '59', '32B', '39A', '39C', '41a', '42C', '42a',
            '42M', '42P', '43P', '43T', '44A', '44E', '44F', '44B', '44C', '44D', '45A', '46A', '47A', '71B', '48', '49',
            '53a', '78', '57a', '72'
        ]
        formatted_lc = []
        for field in lc_fields:
            value = getattr(self, f'f_{field}', None)
            logger.info("FORMATTEDLC:%s",value)
            if value:
                formatted_lc.append(f'{field}: {value}')
                logger.info("FORMATTEDLC2:%s",formatted_lc)
        return '\n'.join(formatted_lc)
    
    @fields.depends('format_lc')
    def on_change_with_lc(self):
        if self.format_lc:
            return self.get_formatted_lc()
        else:
            return ""