import base64
import tempfile
import hashlib
import json
import math
import os
from datetime import datetime
from odoo import models, fields, _
from tbc_bank_integration_service_lib.client import TBCBankClient
from odoo.exceptions import UserError


BANKS = {
    "NB": {"name": "National Bank of Georgia", "code": "BNLNGE22"},
    "TR": {"name": "State Treasury", "code": "TRESGE22"},
    "BG": {"name": 'JSC "Bank of Georgia"', "code": "BAGAGE22"},
    "BS": {"name": 'JSC "BasisBank"', "code": "CBASGE22"},
    "BT": {"name": 'JSC "Silk Bank"', "code": "DISNGE22"},
    "CR": {"name": 'JSC "Cartu Bank"', "code": "CRTUGE22"},
    "HB": {"name": 'JSC "Halyk Bank Georgia"', "code": "HABGGE22"},
    "KS": {"name": 'JSC "Terabank"', "code": "TEBAGE22"},
    "LB": {"name": 'JSC "Liberty Bank"', "code": "LBRTGE22"},
    "PC": {"name": 'JSC "ProCredit Bank"', "code": "MIBGGE22"},
    "TB": {"name": 'JSC "TBC Bank"', "code": "TBCBGE22"},
    "VT": {"name": 'JSC "VTB Bank Georgia "', "code": "UGEBGE22"},
    "ZB": {"name": 'JSC "Ziraat Bank Georgia"', "code": "TCZBGE22"},
    "PB": {"name": 'JSC “Pasha Bank Georgia”', "code": "PAHAGE22"},
    "IS": {"name": 'JSC "Isbank Georgia"', "code": "ISBKGE22"},
    "CD": {"name": 'JSC "Credo Bank"', "code": "JSCRGE22"},
    "PS": {"name": 'JSC "Paysera Bank Georgia"', "code": "PSRAGE22"},
    "HS": {"name": 'JSC "HASH Bank"', "code": "HAJSGE22"},
    "PV": {"name": 'JSC "Pave Bank Georgia"', "code": "PAVEGE22"},
}


class BankMovements(models.Model):
    _name = 'bank.raw.movements'
    _description = 'Bank Movements'

    json_data = fields.Json(string="Json Data")
    json_hash_code = fields.Char(string="Hash Code")
    bid = fields.Char(string="Movement Id")

    parent_id = fields.Many2one('bank.raw.movements', string="Parent Record")
    history_ids = fields.One2many(comodel_name="bank.raw.movements", inverse_name='parent_id', string="History")
    
    def create_or_update_raw_data(self, data, model, bid):
        json_data = json.dumps(data, sort_keys=True, indent=4, ensure_ascii=False)
        hash_object = hashlib.sha256(json_data.encode())
        hash_hex = hash_object.hexdigest()
        
        found_raw_record = self.env[model].search([
            ('bid', '=', bid),
        ])
        
        if found_raw_record:
            if found_raw_record.json_hash_code != hash_hex:
                # found_raw_record.write({
                #     'json_data': json_data,
                #     'json_hash_code': hash_hex
                # })
                new_created_record = self.env[model].create({
                    'json_data': json_data,
                    'json_hash_code': hash_hex,
                    'bid': bid,
                })
                found_raw_record.parent_id = new_created_record.id
        else:
            found_raw_record = self.env[model].create({
                'json_data': json_data,
                'json_hash_code': hash_hex,
                'bid': bid
            })
    
    def get_movements(self):
        client = self.env['bank.settings'].get_request_object()
        today_formatted_date = datetime.now().strftime('%Y-%m-%dT00:00:00.000')

        res = client.get_account_movements_by_date_range('111111', '2024-01-01T00:00:00.000', today_formatted_date)
        self.create_or_update_raw_data(res, 'bank.raw.movements', res['data'])
        pages = math.ceil(int(res['data']['pager']['totalcount']) / int(res['data']['pager']['pagesize']))
        if pages > 1:
            for page in range(1, pages):
                res = client.get_account_movements_by_date_range_next_page('111111', page, 700, '2024-01-01T00:00:00.000', today_formatted_date)
                self.create_or_update_raw_data(res, 'bank.raw.movements', res['data'])

    def process_movements(self):
        to_process_movements = self.env['bank.raw.movements'].search([])
        for info in to_process_movements:
            data = json.loads(info.json_data)

            for movement in data['data']['movements']:
                account_number = movement['accountNumber']
                account_name = movement['accountName']
                amount = movement['amount']['amount']
                currency = movement['amount']['currency']
                iban_code = account_number[4:6]
                description = movement['description']
                comment = movement['additionalInformation']
                partner_name = movement['partnerName']
                taxpayer_name = movement['taxpayerName']

                if movement['debitCredit'] == '0':
                    amount = float(amount) * -1

                currency_id = self.env['res.currency'].search([('name', '=', currency)])

                found_bank = self.env['brosse.bank'].search([('iban_code', '=', iban_code)])

                if found_bank:
                    bank_id = found_bank.id
                else:
                    bank_id = self.env['brosse.bank'].create({
                        'name': BANKS[iban_code]['name'],
                        'bank_code': BANKS[iban_code]['code'],
                        'iban_code': iban_code
                    }).id

                found_bank_account = self.env['brosse.bank.account'].search([
                    ('account_number', '=', account_number), 
                    ('currency_id', '=', currency_id.id)])

                if found_bank_account:
                    bank_account_id = found_bank_account.id
                else:
                    bank_account_id = self.env['brosse.bank.account'].create({
                        'bank_ids': [(4, bank_id)],
                        'holder_name': account_name,
                        'currency_id': currency_id.id,
                        'account_number': account_number,
                    }).id

                self.env['brosse.bank.deposits'].create({
                    'bank_account_id': bank_account_id,
                    'amount': amount,
                    'currency_id': currency_id.id,
                    'description': description,
                    'comment': comment,
                    'partner_name': partner_name,
                    'taxpayer_name': taxpayer_name
                })
        




# movement_id = '013762510743.2'
# movements_by_id = client.get_account_movements_by_id('111111', movement_id)
# self.create_or_update_raw_data(movements_by_id, 'bank.raw.movements', movements_by_id['data'].get('movementId'))
    