import json
from pathlib import Path

from app.core.config import settings


class KBService:
    def __init__(self) -> None:
        self.path = Path(settings.FLOWS_FILE)
        self.data = self._load_data()

    def _load_data(self) -> dict:
        if not self.path.exists():
            return {"categories": []}
        with open(self.path, "r", encoding="utf-8") as f:
            return json.load(f)

    def reload(self) -> None:
        self.data = self._load_data()

    def save(self) -> None:
        with open(self.path, "w", encoding="utf-8") as f:
            json.dump(self.data, f, indent=2, ensure_ascii=False)

    def get_categories(self) -> list[dict]:
        return self.data.get("categories", [])

    def get_category(self, category_code: str) -> dict | None:
        for category in self.get_categories():
            if category.get("code") == category_code:
                return category
        return None

    def add_category(self, code: str, title: str) -> dict:
        if self.get_category(code):
            raise ValueError("Category code already exists")

        category = {
            "code": code.strip(),
            "title": title.strip(),
            "sub_options": []
        }
        self.data["categories"].append(category)
        self.save()
        return category

    def update_category(self, category_code: str, title: str) -> dict:
        category = self.get_category(category_code)
        if not category:
            raise ValueError("Category not found")

        category["title"] = title.strip()
        self.save()
        return category

    def delete_category(self, category_code: str) -> None:
        categories = self.get_categories()
        new_categories = [c for c in categories if c.get("code") != category_code]
        if len(new_categories) == len(categories):
            raise ValueError("Category not found")
        self.data["categories"] = new_categories
        self.save()

    def get_sub_options(self, category_code: str) -> list[dict]:
        category = self.get_category(category_code)
        if not category:
            return []
        return category.get("sub_options", [])

    def get_sub_option(self, category_code: str, sub_code: str) -> dict | None:
        for sub_option in self.get_sub_options(category_code):
            if sub_option.get("code") == sub_code:
                return sub_option
        return None

    def add_sub_option(self, category_code: str, code: str, title: str, steps: list[str]) -> dict:
        category = self.get_category(category_code)
        if not category:
            raise ValueError("Category not found")

        if self.get_sub_option(category_code, code):
            raise ValueError("Issue code already exists in this category")

        item = {
            "code": code.strip(),
            "title": title.strip(),
            "steps": [s.strip() for s in steps if s.strip()]
        }
        category["sub_options"].append(item)
        self.save()
        return item

    def update_sub_option(self, category_code: str, sub_code: str, title: str, steps: list[str]) -> dict:
        item = self.get_sub_option(category_code, sub_code)
        if not item:
            raise ValueError("Issue not found")

        item["title"] = title.strip()
        item["steps"] = [s.strip() for s in steps if s.strip()]
        self.save()
        return item

    def delete_sub_option(self, category_code: str, sub_code: str) -> None:
        category = self.get_category(category_code)
        if not category:
            raise ValueError("Category not found")

        current = category.get("sub_options", [])
        new_items = [i for i in current if i.get("code") != sub_code]
        if len(new_items) == len(current):
            raise ValueError("Issue not found")

        category["sub_options"] = new_items
        self.save()