from collections import defaultdict

from eam_b2c_helper import b2c
from eam_db_helper import db


class UserDocExpiries:
    def __init__(self, db, company_id: str, b2c_helper) -> None:
        self.db = db
        self.company_id = company_id
        self.b2c_helper = b2c_helper

    def get_user_docs(self):
        user_docs = self.db.get_results(
            f"SELECT * FROM c WHERE c.type = 'userDoc' and c.companyId = '{self.company_id}'")

        return user_docs

    def get_users(self):
        users = self.b2c_helper.get_users(
            company_id=self.company_id)

        return users

    def get_user_doc_questions(self, user_docs):
        user_doc_ids = [item.get('id') for item in user_docs if item.get('id')]
        question_docs = self.db.get_results(
            f"SELECT * FROM c WHERE c.type = 'userDocQuestion' and ARRAY_CONTAINS(@user_doc_ids, c.userDocId) and c.key = 'expiry_date'",
            parameters=[{'name': '@user_doc_ids', 'value': user_doc_ids}]
        )

        return question_docs

    def extract_expiry_date(self, user_doc):
        values = (user_doc.get('ocrOutput') or {}).get('values') or []
        for item in values:
            if item.get('key') == 'expiry_date':
                updated_value = item.get('updatedValue', '')
                if updated_value != '':
                    return updated_value
                return item.get('ocrValue') or ''
        return ''

    def extract_question_expiry_date(self, question_doc):
        updated_value = question_doc.get('updatedValue', '')
        if updated_value != '':
            return updated_value
        return question_doc.get('answer') or ''

    def build_worker_doc_matrix(self, users, user_docs, user_doc_questions):
        doc_types = sorted({item.get('docType')
                            for item in user_docs if item.get('docType')})

        question_expiries_by_user_doc = {
            item.get('userDocId'): self.extract_question_expiry_date(item)
            for item in user_doc_questions
            if item.get('userDocId')
        }

        user_doc_expiries = defaultdict(dict)
        for item in user_docs:
            user_doc_id = item.get('id')
            user_id = item.get('userId')
            doc_type = item.get('docType')
            if user_id and doc_type:
                expiry_date = self.extract_expiry_date(
                    item) or question_expiries_by_user_doc.get(user_doc_id, '')
                if expiry_date:
                    user_doc_expiries[user_id][doc_type] = expiry_date
                else:
                    user_doc_expiries[user_id].setdefault(doc_type, '')

        headers = ['Worker Name', *doc_types]
        rows = []
        for user in users:
            user_id = user.get('id')
            worker_name = user.get('displayName', '')
            doc_expiries = user_doc_expiries.get(user_id, {})
            row = {
                'Worker Name': worker_name,
                **{doc_type: doc_expiries.get(doc_type, '') for doc_type in doc_types}
            }
            if any(row.get(doc_type, '') != '' for doc_type in doc_types):
                rows.append(row)

        return headers, rows

    def build_user_doc_expiries_report(self) -> dict:
        user_docs = self.get_user_docs()
        users = self.get_users()
        user_doc_questions = self.get_user_doc_questions(user_docs)

        headers, rows = self.build_worker_doc_matrix(
            users, user_docs, user_doc_questions)

        return {
            'file_name': 'User_Ticket_Expiries.csv',
            'headers': headers,
            'rows': rows,
        }
