import json
import os

class TourLauncher:
    def __init__(self, tours_file="sitemap/tours.json", progress_file="data/tour_progress.json"):
        self.tours_file = tours_file
        self.progress_file = progress_file
        self.tours = self._load_tours()
        self.progress = self._load_progress()

    def _load_tours(self):
        """Loads tour definitions from the tours.json file."""
        try:
            with open(self.tours_file, 'r') as f:
                return json.load(f)
        except FileNotFoundError:
            print(f"Error: Tours file not found at {self.tours_file}")
            return {}
        except json.JSONDecodeError:
            print(f"Error: Invalid JSON format in {self.tours_file}")
            return {}

    def _load_progress(self):
        """Loads tour progress from the tour_progress.json file."""
        try:
            if os.path.exists(self.progress_file):
                with open(self.progress_file, 'r') as f:
                    return json.load(f)
            else:
                return {}
        except json.JSONDecodeError:
            print(f"Error: Invalid JSON format in {self.progress_file}")
            return {}

    def _save_progress(self):
        """Saves the current tour progress to the tour_progress.json file."""
        try:
            os.makedirs(os.path.dirname(self.progress_file), exist_ok=True) # Ensure directory exists
            with open(self.progress_file, 'w') as f:
                json.dump(self.progress, f, indent=4)
        except Exception as e:
            print(f"Error saving progress: {e}")

    def list_tours(self):
        """Lists available tours in CLI format."""
        if not self.tours:
            print("No tours available.")
            return

        print("Available Tours:")
        for i, tour_name in enumerate(self.tours.keys()):
            print(f"{i+1}. {tour_name}")

    def launch_tour(self, tour_index):
        """Launches the selected tour and guides the user through it."""
        tour_names = list(self.tours.keys())
        if not (1 <= tour_index <= len(tour_names)):
            print("Invalid tour selection.")
            return

        tour_name = tour_names[tour_index - 1]
        tour_data = self.tours[tour_name]

        if tour_name not in self.progress:
            self.progress[tour_name] = {"completed_steps": []}

        completed_steps = self.progress[tour_name]["completed_steps"]

        print(f"\nStarting tour: {tour_name}")

        for i, step in enumerate(tour_data["steps"]):
            if i + 1 in completed_steps:
                print(f"\nStep {i+1}: {step['component']} - {step['description']} (Completed)")
                continue

            print(f"\nStep {i+1}: {step['component']} - {step['description']}")
            while True:
                action = input("Enter 'c' to mark as complete, 'q' to quit tour: ").lower()
                if action == 'c':
                    completed_steps.append(i + 1)
                    self.progress[tour_name]["completed_steps"] = completed_steps
                    self._save_progress()
                    print("Step completed.")
                    break
                elif action == 'q':
                    print("Tour interrupted. Progress saved.")
                    return
                else:
                    print("Invalid input. Please enter 'c' or 'q'.")

        print(f"\nTour '{tour_name}' completed!")
        self.progress[tour_name]["completed"] = True
        self._save_progress()


def main():
    """Main function to interact with the user and launch tours."""
    launcher = TourLauncher()
    while True:
        launcher.list_tours()
        try:
            selection = input("Enter the number of the tour to launch (or 'q' to quit): ")
            if selection.lower() == 'q':
                break
            tour_index = int(selection)
            launcher.launch_tour(tour_index)
        except ValueError:
            print("Invalid input. Please enter a number or 'q'.")
        except Exception as e:
            print(f"An unexpected error occurred: {e}")


if __name__ == "__main__":
    main()