from .service import get_service
from googleapiclient.errors import HttpError

def create_docs(doc_title: str)-> dict:
    """
    Creates a Google Docs document that you can use.

    Args:
        doc_title (str): The title of the document.

    Returns:
         dict: Confirmation of the creation and the doc ID.
    
    Example:
        ```python
        def test_create_docs():
            try:
                title= 'Testing'
                docs_creation = create_docs(
                    doc_title= title,
                )
                return f'Test case passed: {docs_creation}'
            except Exception as e:
                return f'Error creating docs: {e}'
        ```
    """
    try:
        service= get_service(service_name= 'docs')
        doc = service.documents().create(body={
            'title': doc_title,
        }).execute()
        return {
            'message': 'Document created successfully.',
            'doc_id': doc.get('documentId'),
        }
    except HttpError as error:
        raise Exception(f" Error {error}")

def insert_text(doc_id: str, text: str, start: int= 1)-> str:
    """
    To insert the text into Google Docs document.

    Basically to work with the addition of text in the Google Docs, we have to consider index.
    And we have to properly add text in each tab by mentioning each index.
    So it is just converting the text into list of paragraphs by splitting the
    text on the double line, and then It will add each paragraph to the list.

    So with this technique the paragraphs will be properly added in the doc. But if the function is
    called on the doc that already has the text; It will move the text ahead, and it will add the new given text
    in the start.

    Args:
        doc_id (str): The id of the document in which you want to insert the text.
        text (str): The text to add.
        start (int, optional): The index of the first paragraph to add. Basically purpose of this is that when we add text in the end (in the update_doc function) we reuse this insert function and just give it the last index as start. So by default its value is set to 1 because in this function it will always add the text in the start.

    Returns:
        Confirmation of the addition of the text.
    
    Example:
        ```python
        def test_insert_text():
            try:
                doc_id= '149SxkXIxroJK0zC-Y5NTaWmTFehsSSpeZ8SyFeMwoB4'
                text= '''
                Hello.
                
                My name is Tester.
                
                I am Testing this insertion of text in the google doc.
                '''
                docs_creation = insert_text(
                    doc_id= doc_id,
                    text= text,
                )
                return f'Test case passed: {docs_creation}'
            except Exception as e:
                return f'Error Inserting Text in docs: {e}'

        ```
    """
    try:
        paragraphs= text.split('\n\n')
        requests= [
            {
                'insert_text':
                    {
                        'location': {
                            'index': index
                        },
                        'text': text + "\n"
                    }
            }
            for index, text in enumerate(paragraphs, start= start)
        ]
        service= get_service(service_name= 'docs')
        result= service.documents().batchUpdate(
            documentId= doc_id,
            body={
                'requests': requests
            }
        ).execute()
        return result
    except HttpError as error:
        raise Exception(f" Error {error}")

def get_docs_content(doc_id: str)-> str:
    """
    To get the content of the Google Docs document. It just brings the normal text; no style. It does take care of the spaces.

    Args:
        doc_id (str): The id of the document of which you want to get the content.

    Returns:
        str: The content of the document.
    
    Example:
        ```python
        def test_get_docs_content():
            try:
                doc_id = '149SxkXIxroJK0zC-Y5NTaWmTFehsSSpeZ8SyFeMwoB4'
                content = get_docs_content(
                    doc_id=doc_id,)
                return f'Test case passed: {content}'
            except Exception as e:
                return f'Error Getting Text from doc: {e}'
        ```
    """
    try:
        content= ''
        service= get_service(service_name= 'docs')
        doc = service.documents().get(documentId= doc_id).execute()
        for text_index in doc['body']['content']:
            for key, value in text_index.items():
                if key== 'paragraph':
                    content+= value['elements'][0]['textRun']['content']
        return content
    except HttpError as error:
        raise Exception(f" Error {error}")

def delete_doc(doc_id: str)-> str:
    """
    To Delete the Google Docs document. It used the drive service to delete the Google Docs document
    because Google Doc Service does not have deletion functionality.

    Args:
        doc_id (str): The id of the document to delete.

    Returns:
        str: The confirmation of the deletion.
    
    Example:
        ```python
        def test_delete_doc():
            try:
                doc_id = '1gec6zFOtrOkweHLbCr9nq8C1ryxlbM5oDRhgYEIa22Q'
                deletion = delete_doc(
                    doc_id=doc_id,)
                return f'Test case passed: {deletion}'
            except Exception as e:
                return f'Error Getting deleting doc: {e}'
        ```
    """
    try:
        service= get_service(service_name= 'drive')
        service.files().delete(fileId= doc_id).execute()
        return f"Document with Id: {doc_id} has been deleted."
    except HttpError as error:
        raise Exception(f" Error {error}")

def update_doc(doc_id: str, text: str)-> str:
    """
    Module to update the document, It is different from insert_text functionality in the way that
    It adds the given text in the end of the document. On the other hand insert_text function
    adds the text in the start of the document regardless if the document is empty or have any
    previous text.

    I did not find any solution for adding text in the end from Google official documentation;
    So this is the custom solution and here is how it tries to add text in the end:
    - Gets the content of the doc.
    - Figure out the last end index where text is present.
    - Just use insert_text function to add the text in the end by giving it where to start from via 'start' parameter.

    Args:
        doc_id (str): The id of the document to update.
        text (str): The text to add.

    Returns:
        str: The Confirmation of the addition of the text.
    
    Example:
        ```python
        def test_update_doc():
            try:
                doc_id = '149SxkXIxroJK0zC-Y5NTaWmTFehsSSpeZ8SyFeMwoB4'
                text = '''
                This is to test update feature ok.
                
                
                I am testing the update feature.
                
                
                I am done testing. 
                '''
                docs_creation = update_doc(
                    doc_id= doc_id,
                    text= text,
                )
                return f'Test case passed: {docs_creation}'
            except Exception as e:
                return f'Error Inserting Text in docs: {e}'
        ```
    """
    try:
        service= get_service(service_name= 'docs')
        doc_content= service.documents().get(documentId= doc_id).execute()
        last_index= doc_content['body']['content'][-1]['endIndex']-1
        update_result= insert_text(
            doc_id= doc_id,
            text= text,
            start= last_index
        )
        return update_result
    except HttpError as error:
        raise Exception(f" Error {error}")
