# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/40_nlp.ipynb (unless otherwise specified).

__all__ = ['Textual']

# Cell
from bs4 import BeautifulSoup
import requests
import logging
from ipywidgets import interact, interact_manual, FileUpload
from pathlib import Path
from forgebox.html import DOM

# Cell
class Textual:
    """
    Obtain and manage textual data
    """

    def __init__(self, text: str):
        self.text = text.replace("\n", " ").replace("\r", "")

    def __repr__(self) -> str:
        return f"""Text ({len(self.text)} chars), textual(),
    train_path, val_path = textual.create_train_val()"""

    def __call__(self, page_size: int = 1000) -> None:
        """
        Previewing the first 200(or less) pages
        - page_size: character number each page
        """
        logging.info(f"Previewing the first 200 pages")

        @interact
        def show_text(page=(0, min(len(self.text)//page_size-1, 200), 1)):
            display(self.text[page*page_size: (page+1)*page_size])

    @classmethod
    def from_url(cls, url: str):
        res = requests.get(url)
        if res.status_code == 200:
            res.encoding = 'utf-8'
            headers = res.headers
            if "html" in str(headers).lower():
                text = BeautifulSoup(res.text).text
            else:
                text = res.text
            obj = cls(text)
            obj.path = "./text_data.txt"
            with open(obj.path, "w") as f:
                f.write(obj.text)
            return obj
        else:
            raise ConnectionError(f"Error downloading: {url}")

    @classmethod
    def from_path(cls, path: Path):
        """
        Load a textual object from system path
        """
        if Path(path).exists() == False:
            raise FileExistsError(f"Can not find {path}")
        with open(path, ) as f:
            obj = cls(f.read())
            obj.path = path
            return obj

    @classmethod
    def from_upload(
        cls,
        path: Path = Path("./uploaded_file.txt")
    ):
        DOM("🗃 Please upload a text file ended in .txt", "h4")()
        my_manual = interact_manual.options(manual_name="Upload")
        @my_manual
        def create_upload(btn_upload = FileUpload(description="Choose File")):
            text = list(btn_upload.values())[-1]['content'].decode()
            with open(path, "w") as f:
                f.write(text)
            return path
        def uploaded():
            result = create_upload.widget.result
            if result is None:
                raise FileExistsError(
                    "You have to upload the txt file first")
            return cls.from_path(result)
        return uploaded


    def create_train_val(
            self,
            valid_ratio=.2,
            train_path="./train_text.txt",
            val_path="./val_text.txt"):
        """
        create 2 files:
        - ./train_text.txt
        - ./val_text.txt
        """
        split = int(len(self.text)*(valid_ratio))
        with open(train_path, "w") as f:
            f.write(self.text[split:])
        with open(val_path, "w") as f:
            f.write(self.text[:split])
        return train_path, val_path