from abc import ABC, abstractmethod
import numpy as np

from models.core import GPSPoint
from models.satellite import TileCandidate
from models.processing import AlignmentResult


class GlobalPlaceRecognitionBase(ABC):
    @abstractmethod
    async def extract_global_descriptor(self, image: np.ndarray) -> np.ndarray:
        pass

    @abstractmethod
    async def search_candidates(
        self,
        descriptor: np.ndarray,
        search_center: GPSPoint,
        search_radius: float,
        top_k: int = 10,
    ) -> list[TileCandidate]:
        pass

    @abstractmethod
    async def verify_candidate(
        self, uav_image: np.ndarray, satellite_image: np.ndarray
    ) -> AlignmentResult:
        pass

    @abstractmethod
    async def index_tile(
        self, tile_image: np.ndarray, tile_id: str, gps_center: GPSPoint
    ) -> bool:
        pass

    @abstractmethod
    async def build_index_for_area(
        self, nw: GPSPoint, se: GPSPoint, zoom: int
    ) -> int:
        pass

    @abstractmethod
    async def get_indexed_tile_count(self) -> int:
        pass

