import os
import datetime
from kivy.network.urlrequest import UrlRequest
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.scrollview import ScrollView
from kivy.uix.popup import Popup
from kivy.uix.progressbar import ProgressBar
from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.label import MDLabel
from kivymd.uix.button import MDRaisedButton, MDFlatButton
from kivymd.uix.dialog import MDDialog
from kivymd.uix.tab import MDTabsBase, MDTabs

from kivy.uix.textinput import TextInput  # Added import for TextInput

class ScrapeTab(MDBoxLayout, MDTabsBase):
    def __init__(self, **kwargs):
        super(ScrapeTab, self).__init__(**kwargs)
        self.orientation = "vertical"
        self.md_bg_color = [1, 1, 1, 1]
        self.log_output = ScrollView(size_hint=(1, 0.6))
        self.log_text = Label(text="")
        self.log_output.add_widget(self.log_text)
        self.progress_label = Label(text="Progress: 0%")
        self.progress_bar = ProgressBar(max=100)
        self.cancel_button = Button(text="Cancel", disabled=True, on_release=self.cancel_scraping)
        self.pause_button = Button(text="Pause", on_release=self.pause_scraping)
        self.resume_button = Button(text="Resume", disabled=True, on_release=self.resume_scraping)
        self.thread_entry = BoxLayout(orientation='horizontal')
        self.thread_entry.add_widget(Label(text="Number of threads: "))
        self.thread_input = TextInput(text="1")
        self.thread_entry.add_widget(self.thread_input)
        self.thread_button = Button(text="Set Threads", on_release=self.set_threads)
        self.thread_entry.add_widget(self.thread_button)
        self.add_widget(self.log_output)
        self.add_widget(self.progress_label)
        self.add_widget(self.progress_bar)
        self.add_widget(self.cancel_button)
        self.add_widget(self.pause_button)
        self.add_widget(self.resume_button)
        self.add_widget(self.thread_entry)
        self.cancelled = False
        self.paused = False
        self.num_threads = 1
        self.scraped_pages = 0
        self.num_pages = 100

    def scrape_data(self):
        while self.scraped_pages < self.num_pages:
            if self.paused:
                continue
            # Scraping logic goes here
            self.scraped_pages += 1
            self.update_progress()
            if self.cancelled:
                self.log_message("Scraping cancelled.")
                break
        if not self.cancelled:
            self.log_message("Scraping complete.")

    def log_message(self, message):
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"[{timestamp}] {message}\n"
        self.log_text.text += log_entry
        self.log_output.scroll_y = 0

    def pause_scraping(self, *args):
        self.paused = True
        self.cancel_button.disabled = False
        self.pause_button.disabled = True
        self.resume_button.disabled = False
        self.log_message("Scraping paused.")

    def resume_scraping(self, *args):
        self.paused = False
        self.cancel_button.disabled = True
        self.pause_button.disabled = False
        self.resume_button.disabled = True
        self.log_message("Resuming scraping.")

    def cancel_scraping(self, *args):
        self.cancelled = True
        self.cancel_button.disabled = True

    def set_threads(self, *args):
        try:
            new_threads = int(self.thread_input.text)
            if new_threads > 0:
                self.num_threads = new_threads
                self.log_message(f"Number of threads set to: {self.num_threads}")
            else:
                self.log_message("Invalid number of threads. Please enter a positive integer.")
        except ValueError:
            self.log_message("Invalid input for the number of threads. Please enter a positive integer.")

    def update_progress(self):
        if self.cancelled:
            self.progress_label.text = f"Progress: Cancelled"
        else:
            self.progress = int((self.scraped_pages / self.num_pages) * 100)
            self.progress_bar.value = self.progress
            self.progress_label.text = f"Progress: {self.progress}%"

class VisualizeTab(MDBoxLayout, MDTabsBase):
    def __init__(self, **kwargs):
        super(VisualizeTab, self).__init__(**kwargs)
        self.orientation = "vertical"
        self.md_bg_color = [1, 1, 1, 1]
        self.visualization_output = ScrollView(size_hint=(1, 0.8))
        self.visualization_text = MDLabel(text="")
        self.visualization_output.add_widget(self.visualization_text)
        visualize_button = MDRaisedButton(text="Visualize Data", on_release=self.visualize_data)
        self.add_widget(self.visualization_output)
        self.add_widget(visualize_button)

    def visualize_data(self, *args):
        if not MDApp.get_running_app().root.data:
            MDApp.get_running_app().root.log_message("No data to visualize.")
            return
        categories = set()
        data_count = {}
        for item in MDApp.get_running_app().root.data:
            category = item['title']
            categories.add(category)
            data_count[category] = data_count.get(category, 0) + 1
        self.visualization_text.text = "\n".join([f"{category}: {count}" for category, count in data_count.items()])

class WebScraperApp(MDApp):
    def __init__(self, **kwargs):
        super(WebScraperApp, self).__init__(**kwargs)
        self.title = "Web Scraper"
        self.data = []  # Store scraped data

    def build(self):
        self.theme_cls.primary_palette = "Green"
        self.theme_cls.accent_palette = "Amber"
        root = MDBoxLayout(orientation='vertical')
        self.tab = MDTabs()
        self.tab.add_widget(ScrapeTab(text="Scrape"))
        self.tab.add_widget(VisualizeTab(text="Visualize"))
        root.add_widget(self.tab)
        return root

    def log_message(self, message):
        self.tab.get_tab_by_name('Scrape').log_message(message)

if __name__ == "__main__":
    WebScraperApp().run()