import abc
from abc import ABC, abstractmethod
from dataclasses import dataclass

from kiutils.utils.strings import dequote as dequote

@dataclass
class Position:
    X: float = ...
    Y: float = ...
    angle: float | None = ...
    unlocked: bool = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Position: ...
    def to_sexpr(self) -> str: ...

@dataclass
class Coordinate:
    X: float = ...
    Y: float = ...
    Z: float = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Coordinate: ...
    def to_sexpr(self, indent: int = 0, newline: bool = False) -> str: ...

@dataclass
class ColorRGBA:
    R: int = ...
    G: int = ...
    B: int = ...
    A: int = ...
    precision: int | None = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> ColorRGBA: ...
    def to_sexpr(self, indent: int = 0, newline: bool = False) -> str: ...

@dataclass
class Stroke:
    width: float = ...
    type: str | None = ...
    color: ColorRGBA | None = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Stroke: ...
    def to_sexpr(self, indent: int = 2, newline: bool = True) -> str: ...

@dataclass
class Font:
    face: str | None = ...
    height: float = ...
    width: float = ...
    thickness: float | None = ...
    bold: bool = ...
    italic: bool = ...
    lineSpacing: float | None = ...
    color: ColorRGBA | None = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Font: ...
    def to_sexpr(self, indent: int = 0, newline: bool = False) -> str: ...

@dataclass
class Justify:
    horizontally: str | None = ...
    vertically: str | None = ...
    mirror: bool = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Justify: ...
    def to_sexpr(self, indent: int = 0, newline: bool = False) -> str: ...

@dataclass
class Effects:
    font: Font = ...
    justify: Justify = ...
    hide: bool = ...
    href: str | None = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Effects: ...
    def to_sexpr(self, indent: int = 0, newline: bool = True) -> str: ...

@dataclass
class Net:
    number: int = ...
    name: str = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Net: ...
    def to_sexpr(self, indent: int = 0, newline: bool = False) -> str: ...

@dataclass
class Group:
    name: str = ...
    locked: bool = ...
    id: str = ...
    members: list[str] = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Group: ...
    def to_sexpr(self, indent: int = 2, newline: bool = True) -> str: ...

@dataclass
class PageSettings:
    paperSize: str = ...
    width: float | None = ...
    height: float | None = ...
    portrait: bool = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> PageSettings: ...
    def to_sexpr(self, indent: int = 2, newline: bool = True) -> str: ...

@dataclass
class TitleBlock:
    title: str | None = ...
    date: str | None = ...
    revision: str | None = ...
    company: str | None = ...
    comments: dict[int, str] = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> TitleBlock: ...
    def to_sexpr(self, indent: int = 2, newline: bool = True) -> str: ...

@dataclass
class Property:
    key: str = ...
    value: str = ...
    id: int | None = ...
    position: Position = ...
    effects: Effects | None = ...
    showName: bool = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Property: ...
    def to_sexpr(self, indent: int = 4, newline: bool = True) -> str: ...

@dataclass
class RenderCachePolygon:
    pts: list[Position] = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> RenderCachePolygon: ...
    def to_sexpr(self, indent: int = 6, newline: bool = True) -> str: ...

@dataclass
class RenderCache:
    text: str = ...
    id: int = ...
    polygons: list[Position] = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> RenderCache: ...
    def to_sexpr(self, indent: int = 4, newline: bool = True) -> str: ...

@dataclass
class Fill:
    type: str = ...
    color: ColorRGBA | None = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Fill: ...
    def to_sexpr(self, indent: int = 4, newline: bool = True) -> str: ...

@dataclass
class Image:
    position: Position = ...
    scale: float | None = ...
    data: list[str] = ...
    uuid: str | None = ...
    layer: str | None = ...
    @classmethod
    def from_sexpr(cls, exp: list) -> Image: ...
    def to_sexpr(self, indent: int = 2, newline: bool = True) -> str: ...

@dataclass
class ProjectInstance(ABC, metaclass=abc.ABCMeta):
    name: str = ...
    @abstractmethod
    def from_sexpr(cls, exp: list) -> ProjectInstance: ...
    @abstractmethod
    def to_sexpr(self, indent: int = 2, newline: bool = True) -> str: ...
