from beancount.ingest import importer
from beancount.core import data
from beancount.core.number import D

import csv
import datetime

class MyCSVImporter(importer.ImporterProtocol):
    """A Beancount importer for CSV files"""

    def identify(self, file):
        return file.name.endswith('.csv')

    def file_account(self, file):
        return "Assets:Bank:PostbankGiro"

    def file_date(self, file):
        """Returns the unique date of the file, if any."""
        # Optioneel: als je bestandsnaam een datum bevat
        return None

    def file_name(self, file):
        """Returns the unique name of the file, if any."""
        # Optioneel: als je een unieke naam wilt baseren op het bestand
        return None

    def extract(self, file, existing_entries=None):
        """Extracts entries from a files."""
        entries = []

        # file.contents
        with open(file.name, encoding='utf-8') as f:
            csv_reader = csv.reader(f, delimiter=';')
            # Gebruik enumerate() om een teller (index) te krijgen
            for index, row in enumerate(csv_reader):
                if len(row) < 18 or row[17] != "EUR":
                    continue

                # De index begint bij 0, dus de 12e kolom is index 11.
                # Boekingsdatum = index 0
                # Ontvanger = index 3
                # Omschrijving = index 4
                # Bedrag = index 11
                # Valuta = index 17
                datum_str = row[0]
                ontvanger = row[3]
                omschrijving_str = row[4]
                bedrag_str = row[11]
                valuta = row[17]

                dag, maand, jaar = datum_str.split('.')
                transactie_datum = datetime.date(int(jaar), int(maand), int(dag))
                
                payee = ontvanger
                narration = omschrijving_str
                # Verwijder eerst de duizendtallen-scheidingstekens (de punten)
                bedrag_str = bedrag_str.replace('.', '')
                # Vervang daarna de komma door een punt
                bedrag_str = bedrag_str.replace(',', '.')
                bedrag = D(bedrag_str)
                currency = valuta

                meta = data.new_metadata(file.name, index)

                # Bepaal of het een inkomst of uitgave is op basis van het voorteken van het bedrag.
                if bedrag < D(0):
                    # Uitgave: bedrag is negatief.
                    # Geld gaat van de bankrekening naar een uitgavenrekening.
                    tegenrekening = self._map_payee_to_account(payee + " " + omschrijving_str)

                    #FORMAT: data.Posting(account, units, cost=None, price=None, flag=None, meta=None)
                    postings = [
                        #data.Posting(self.file_account(file), bedrag, currency, None, None, None),
                        data.Posting(self.file_account(file), data.Amount(bedrag, currency), None, None, None, None),
                        #data.Posting(tegenrekening, -bedrag, currency, None, None, None),
                        data.Posting(tegenrekening, data.Amount(bedrag, currency), None, None, None, None),
                    ]
                else:
                    # Inkomsten: bedrag is positief.
                    # Geld gaat van een inkomstenrekening naar de bankrekening.
                    tegenrekening = self._map_payee_to_account(payee + " " + omschrijving_str)

                    #FORMAT: data.Posting(account, units, cost=None, price=None, flag=None, meta=None)
                    postings = [
                        #data.Posting(tegenrekening, -bedrag, currency, None, None, None),
                        data.Posting(tegenrekening, data.Amount(-bedrag, currency), None, None, None, None),
                        #data.Posting(self.file_account(file), bedrag, currency, None, None, None),
                        data.Posting(self.file_account(file), data.Amount(bedrag, currency), None, None, None, None),
                    ]

                transaction = data.Transaction(
                    meta=meta,
                    date=transactie_datum,
                    flag='*',
                    payee=payee,
                    narration=narration,
                    tags=frozenset(),
                    links=frozenset(),
                    postings=postings
                )
                
                entries.append(transaction)
                
        return entries
    
    def _map_payee_to_account(self, payee):
        mapping = {
            "Lohn": "Income:Salaris",
            "Miete": "Expenses:Rent",
            "Sachsen":"Expenses:Electricity",
        }
        for sleutelwoord, rekening in mapping.items():
            if sleutelwoord.lower() in payee.lower():
                return rekening
        
        return "Expenses:Uncategorized"