import csv
import uuid
from .models import Participant, Answer, QuestionPossibility, Possibility
import re
import logging
from django.conf import settings
from django.template.loader import render_to_string
from django.core.mail import send_mail

logger = logging.getLogger(__name__)

def handle_uploaded_file(file, user):
    if file.name.endswith('.csv'):
        handle_csv_file(file, user)
    elif file.name.endswith('.txt'):
        handle_text_file(file, user) 

def handle_csv_file(file, user):
    decoded_file = file.read().decode('utf-8').splitlines()
    reader = csv.DictReader(decoded_file)
    row2 = {}
    for row in reader:
        row2['last_name'] = row['nom']
        row2['first_name'] = row['prenoms']
        row2['email'] = row['email']
        row2['phone'] = row['tel']        
        create_participant(row2, user)
        
def handle_text_file(file, user):
    decoded_file = file.read().decode('utf-8')
    print(decoded_file, type(decoded_file))
    print(decoded_file.splitlines())
    for i in range(1, len(decoded_file.splitlines())):
        last_name, first_name, email, phone = decoded_file.splitlines()[i].split(',')
        row = {'first_name': first_name.strip(), 'last_name': last_name.strip(), 'email': email.strip(), 'phone': phone.strip()}
        create_participant(row, user)


def create_participant(row, user):
    first_name = row.get('first_name')
    last_name = row.get('last_name')
    email = row.get('email')
    phone = row.get('phone')

    Participant.objects.get_or_create(email=email, defaults={
        'user': user,
        'first_name': first_name,
        'last_name': last_name,
        'token': uuid.uuid4(),
        'phone': phone
    })

def extract_number(string):
    match = re.search(r'\d+', string)
    if match:
        return int(match.group())
    else:
        return None
    
    
def poll_questions_stats(poll):
    question_stats = []
    for question in poll.questions.all():
        stats = {'question': question.label, 'type': question.type.label, 'responses': {}}
        
        if question.type.label == 'Libre':
            answers = Answer.objects.filter(question_possibility__question=question)
            stats['responses'] = [answer.content for answer in answers]
        else:
            possibilities = QuestionPossibility.objects.filter(question=question)
            for possibility in possibilities:
                label = possibility.possibility.label if possibility.possibility else 'None'
                stats['responses'][label] = Answer.objects.filter(question_possibility=possibility).count()
        question_stats.append(stats)
    return question_stats

def new_possibilities_ids(possibilities_datas):
    ids = [] # list to store correct possibitities ids
    if possibilities_datas:
        for data in possibilities_datas:
            try:
                ids.append(int(data))
            except ValueError:
                possibility = Possibility(label=data.capitalize())
                possibility.save()
                ids.append(possibility.id)
    return ids


def questionOrder(questions, question):
    """get the order of a question in questions

    Args:
        questions (QuerySet): questions
        question (Question): specific question

    Returns:
        int: the order of the specified question
    """
    return list(questions).index(question) + 1


def getQuestionsByOrder(questions, order):
    """ get the question by its order in the list of questions

    Args:
        questions (QuerySet): queryset of questions
        order (int): order of the question in the list

    Returns:
        Question: the question at the given order
    """
    return list(questions)[order - 1] if order <= len(questions) else None

def getAnsweredQuestions(answers):
    """ get the questions that have been answered

    Args:
        answers (QuerySet): queryset of answers

    Returns:
        QuerySet: queryset of questions that have been answered
    """
    answered_questions = {}
    for answer in answers:
        if not answer.question_possibility.possibility:
            answered_questions[answer.question_possibility.question.id] = answer.content
        else:
            if answer.question_possibility.question.id not in answered_questions.keys():
                answered_questions[answer.question_possibility.question.id] = [answer.question_possibility.possibility.id]
            else:
                answered_questions[answer.question_possibility.question.id].append(answer.question_possibility.possibility.id)
    
    return  answered_questions

def getFirstQuestionNotAnsweredIndex(questions, answered_questions):
    """ get the first question that has not been answered

    Args:
        questions (QuerySet): queryset of questions
        answered_questions (QuerySet): queryset of questions alreday answered
    Returns:
        int: the first question index that has not been answered
    """
    first_unanswered_index = 1
    for index, question in enumerate(questions, start=1):
        if question.id not in answered_questions:
            first_unanswered_index = index
            break
        else:
            first_unanswered_index = index
    return first_unanswered_index

def send_email(subject: str, receivers: list, template: str, context: dict):
    """ send email to the specified receivers

    Args:
        subject (str): email subject
        receivers (list): list of receivers
        template (str): email template
        context (dict): email context
        
    Returns:
        Boolean: True if the email is sent successfully, False otherwise
    """
    try:
        message = render_to_string(template, context)
        print(message)
        send_mail(
            subject, 
            message, 
            settings.EMAIL_HOST_USER,
            recipient_list=receivers,
            fail_silently=True,
            html_message=message
         )
        return True
    except Exception as e:
        logger.error(f"Error while sending email: {e}")
    return False