from typing import List, Dict, Tuple, Any
from app.core.database.operations import get_items_from_database
from app.core.data_validator import check_required_fields_presence, validate_data
from app.services.items_services import add_item_service, update_item_service, delete_item_service


def replace_new_apartments_service(
    building_item_id: int,
    data: Dict[str, Any]
) -> Tuple[Dict[str, Any], List[int]]:
    apartments_data = data.get("apartments", [])

    # Resolve building_id
    matched = get_items_from_database(
        table_name="items",
        conditions={"id": building_item_id}
    )
    if not matched or "ref_item_id" not in matched[0]:
        return {
            "error": f"Building item ID={building_item_id} nije pronađen."}, [400]
    building_id = matched[0]["ref_item_id"]

    # Validation
    apartment_numbers = set()
    for apt in apartments_data:
        if apt["apartment_number"] in apartment_numbers:
            return {
                "error": "Uneti podaci nisu validni",
                "details": "Postoje stanovi sa istim brojem u zgradi"
            }, 422
        apartment_numbers.add(apt["apartment_number"])

        apt['building_id'] = building_id

        req_chk, status = check_required_fields_presence(
            apt, model_name="new_apartment")

        if "error" in req_chk:
            return {
                "error": "Niste uneli sva obavezna polja.",
                "details": req_chk["error"]
            }, status

        val_res, status = validate_data(apt, model_name="new_apartment")
        if "error" in val_res:
            return {
                "error": "Niste uneli validne vrednosti.",
                "details": val_res["error"]
            }, status

    # Fetch all existing apartments for this building
    existing_apartments_data = get_items_from_database(
        table_name="new_apartments",
        conditions={"building_id": building_id}
    )
    existing_by_apartment_number = {
        apt["apartment_number"]: apt
        for apt in existing_apartments_data
    }
    existing_apartment_numbers = set(
        [apt["apartment_number"] for apt in existing_apartments_data])

    # Fetch all new apartments from specific building in items table
    existing_in_items = get_items_from_database(
        table_name="items",
        conditions={"model_name": "new_apartment"}
    )
    for item in existing_in_items:
        for apt in existing_apartments_data:
            if apt["id"] == item["ref_item_id"]:
                apt["item_id"] = item["id"]

    # Handle no longer existing apartments
    for item in existing_apartments_data:
        if item['apartment_number'] not in apartment_numbers:
            response, status_codes = delete_item_service(item['item_id'])
            if isinstance(response, dict) and 'error' in response:
                return (response, status_codes)

    # Handle apartments to add
    for apt in apartments_data:
        if apt["apartment_number"] not in existing_apartment_numbers:
            response, status_codes = add_item_service(
                model_name="new_apartment", item_data=apt)
            if isinstance(response, dict) and 'error' in response:
                return (response, status_codes)

    # Handle apartments to update
    for apt in apartments_data:
        if apt["apartment_number"] in existing_apartment_numbers:
            response, status_codes = update_item_service(
                id=existing_by_apartment_number[apt["apartment_number"]]["item_id"], item_data=apt)
            if isinstance(response, dict) and 'error' in response:
                return (response, status_codes)

    return {}, [200]
