from random import randint
from faker import Faker

from service_app_test.test_application.evyos.datas.company_employee_data import (
    list_options,
)
from service_app_test.test_application.evyos.datas.get_building_types import (
    list_building_types,
)
from service_app_test.test_application.evyos.datas.get_occupants_codes import (
    get_occupants_types,
)
from service_app_test.test_application.evyos.datas.get_type_codes import (
    get_type_codes_key_and_class,
)
from service_app_test.bases import active_and_confirmed


fake = Faker()


post_code_dict = lambda uu_id_street: {
    "post_code": "06690",
    "street_uu_id": uu_id_street,
    **active_and_confirmed,
}
address_dict = lambda post_code_uu_id: {
    "post_code_uu_id": post_code_uu_id,
    "comment_address": "Reşat Nuri Cad No 11",
    "letter_address": "Reşat Nuri Cad No 11 ÇANKAYA ANKARA TÜRKİYE",
    "short_letter_address": "Reşat Nuri Cad No 11 ÇANKAYA ANKARA TÜRKİYE",
    "build_number": "11",
    **active_and_confirmed,
}
build_dict = lambda address_uu_id, build_type_uu_id: {
    "gov_address_code": f"1231231231{randint(0,99)}",
    "build_name": fake.street_name(),
    "build_types_uu_id": build_type_uu_id,
    "max_floor": randint(0, 99),
    "underground_floor": "0",
    "address_uu_id": address_uu_id,
    "build_date": "1970-02-01",
    "decision_period_date": "1970-07-01",
    **active_and_confirmed,
}
build_part_dict = lambda build_uu_id, count, flat_type_uu_id, directions_uu_id: {
    "build_uu_id": build_uu_id,
    "address_gov_code": f"1231231231{randint(0,99)}",
    "part_no": count + 1,
    "part_level": count + 1,
    "build_part_type_uu_id": flat_type_uu_id,
    "part_gross_size": randint(141, 180),
    "part_net_size": randint(80, 140),
    "default_accessory": "Klima",
    "human_livable": True,
    "part_direction_uu_id": directions_uu_id,
    **active_and_confirmed,
}
build_living_space = lambda build_part_uu_id, life_person_uu_id, occupant_type_uu_id: {
    "build_parts_uu_id": build_part_uu_id,
    "person_uu_id": life_person_uu_id,
    "occupant_type_uu_id": occupant_type_uu_id,
    **active_and_confirmed,
}


def create_build_parts(requester, build_uu_id, count: int = 1):
    flat_type = list_building_types(type_code="DAIRE")
    flat_type_uu_id = flat_type["data"][0]["uu_id"]
    directions = get_type_codes_key_and_class(class_name="Directions", key_name="NN")
    directions_uu_id = directions["data"]["uu_id"]

    for count_ in range(count):
        response = requester.post(
            endpoint="/building/parts/create",
            data=build_part_dict(
                build_uu_id=build_uu_id,
                count=count_,
                flat_type_uu_id=flat_type_uu_id,
                directions_uu_id=directions_uu_id,
            ),
        )
        # print("text", response.text)
        # print("json", response.json())
    # return response.json()


def create_post_code(post_code, requester):
    print("post_code", post_code)
    post_code_response = requester.post(
        endpoint="/postcode/create",
        data=post_code,
    )
    print("text", post_code_response.text)
    print("json", post_code_response.json())
    code_response = post_code_response.json()
    return code_response


def create_addresses(address, requester):
    address_response = requester.post(
        endpoint="/address/create",
        data=address,
    )
    print("text", address_response.text)
    print("json", address_response.json())
    return


def create_build_with_address_uu_id(address_dict_with_uu_id, requester):
    response = requester.post(
        endpoint="/building/build/create",
        data={**address_dict_with_uu_id, "build_number": "11"},
    )
    print("text", response.text)
    print("json", response.json())
    return response.json()


def create_build_living_space(living_space_dict, requester):
    response = requester.post(
        endpoint="/building/living_space/create",
        data=living_space_dict,
    )
    # print("text", response.text)
    # print("json", response.json())
    return response.json()


def search_street(search_text, requester):
    response = requester.post(
        endpoint="/address/search",
        data={
            "search": search_text,
            "list_options": {
                "page": 1,
                "size": 30,
            },
        },
    )
    print("text", response.text)
    print("json", response.json())

    for street_data in response.json().get("data"):
        condition_of_street = (
            street_data["AddressCity.city_name"] == "ANKARA"
            and street_data["AddressDistrict.district_name"] == "ÇANKAYA"
        )
        if condition_of_street:
            print("street_uu_id", street_data["AddressStreet.uu_id"])
            return street_data["AddressStreet.uu_id"]


def list_post_codes(requester):
    post_code_response = requester.post(
        endpoint="/postcode/list",
        data=list_options,
    )
    print("text", post_code_response.text)
    print("json", post_code_response.json())
    return post_code_response.json()


def list_addresses(requester):
    address_response = requester.post(
        endpoint="/address/list",
        data=list_options,
    )
    print("text", address_response.text)
    print("json", address_response.json())
    return address_response.json()


def list_building(requester, query=None):
    query_options = list_options
    if query:
        query_options["query"] = query
    response = requester.post(endpoint="/building/build/list", data=query_options)
    print("text", response.text)
    print("json", response.json())
    return response.json()


def list_build_living_space(requester):
    response = requester.post(
        endpoint="/building/living_space/list",
        data=list_options,
    )
    print("text", response.text)
    print("json", response.json())
    return response.json()


def list_building_parts(requester, query: dict = None):
    query_dict = query
    if not query:
        query_dict = {"part_code__contains": ":"}

    response = requester.post(
        endpoint="/building/parts/list",
        data={**list_options, "query": query_dict},
    )
    print("text", response.text)
    print("json", response.json())
    return response.json()


def create_property_owner(
    build_part_uu_id, person_uu_id, occupant_type_flat_owner_uu_id, requester
):
    return create_build_living_space(
        living_space_dict=build_living_space(
            build_part_uu_id=build_part_uu_id,
            life_person_uu_id=person_uu_id,
            occupant_type_uu_id=occupant_type_flat_owner_uu_id,
        ),
        requester=requester,
    )


def create_property_tenant(
    build_part_uu_id, person_uu_id, occupant_type_flat_tenant_uu_id, requester
):
    return create_build_living_space(
        living_space_dict=build_living_space(
            build_part_uu_id=build_part_uu_id,
            life_person_uu_id=person_uu_id,
            occupant_type_uu_id=occupant_type_flat_tenant_uu_id,
        ),
        requester=requester,
    )


def create_property_resident(
    build_part_uu_id, person_uu_id, occupant_type_flat_resident_uu_id, requester
):
    return create_build_living_space(
        living_space_dict=build_living_space(
            build_part_uu_id=build_part_uu_id,
            life_person_uu_id=person_uu_id,
            occupant_type_uu_id=occupant_type_flat_resident_uu_id,
        ),
        requester=requester,
    )


def create_property_observer(build_part_uu_id, person_uu_id, requester):
    return create_build_living_space(
        living_space_dict=build_living_space(
            build_part_uu_id=build_part_uu_id,
            life_person_uu_id=person_uu_id,
            occupant_type_uu_id=None,
        ),
        requester=requester,
    )


def create_occupant_build_manager(
    build_part_uu_id, person_uu_id, occupant_type_flat_manager_uu_id, requester
):
    return create_build_living_space(
        living_space_dict=build_living_space(
            build_part_uu_id=build_part_uu_id,
            life_person_uu_id=person_uu_id,
            occupant_type_uu_id=occupant_type_flat_manager_uu_id,
        ),
        requester=requester,
    )


def get_random_people_list(requester):
    # person_uu_id : 2d5dac99-c445-44fc-a0a5-de97ec65781a is a tenant and lives in the build part as PL and PT
    random_user_list_response = requester.post(
        data={
            "page": 1,
            "size": 70,
            "query": {"created_by": None, "email__contains": "@example."},
        },
        endpoint="/user/list",
    ).json()

    random_user_list = [
        str(user["uu_id"]) for user in random_user_list_response["data"]
    ]
    print("random_user_list", random_user_list)

    random_people_list_response = requester.post(
        data={"page": 1, "size": 70, "query": {"user_uu_id_list": random_user_list}},
        endpoint="/user/list",
    ).json()
    return random_people_list_response["data"]


def assign_random_people_to_build_parts(
    list_of_building_parts, list_of_random_people, occupant_dict, build_uu_id, requester
):

    part_counter = 0
    uu_id_occupant_type_flat_owner = occupant_dict["occupant_type_flat_owner"]
    uu_id_occupant_type_flat_tenant = occupant_dict["occupant_type_flat_tenant"]
    uu_id_occupant_type_flat_manager = occupant_dict["occupant_type_flat_manager"]
    uu_id_occupant_type_flat_resident = occupant_dict["occupant_type_flat_resident"]

    man_room = list_building_parts(
        query={"part_no": "0", "build_uu_id": build_uu_id}, requester=requester
    )
    man_room_uu_id = man_room["data"][0]["uu_id"]

    for i in range(len(list_of_random_people)):
        if i % 2 == 1 and not i == 0:
            if part_counter == len(list_of_building_parts):
                break

            selected_build_part_uu_id = list_of_building_parts[part_counter]["uu_id"]
            part_counter += 1
            # Property Owner
            create_property_owner(
                build_part_uu_id=selected_build_part_uu_id,
                person_uu_id=list_of_random_people[i - 1]["uu_id"],
                occupant_type_flat_owner_uu_id=uu_id_occupant_type_flat_owner,
                requester=requester,
            )

            # Property Tenant
            create_property_tenant(
                build_part_uu_id=selected_build_part_uu_id,
                person_uu_id=list_of_random_people[i]["uu_id"],
                occupant_type_flat_tenant_uu_id=uu_id_occupant_type_flat_tenant,
                requester=requester,
            )

            # Property Tenant Living Space Occupant
            create_property_resident(
                build_part_uu_id=selected_build_part_uu_id,
                person_uu_id=list_of_random_people[i]["uu_id"],
                occupant_type_flat_resident_uu_id=uu_id_occupant_type_flat_resident,
                requester=requester,
            )

            if i == 1:
                create_occupant_build_manager(
                    build_part_uu_id=man_room_uu_id,
                    person_uu_id=list_of_random_people[i]["uu_id"],
                    occupant_type_flat_manager_uu_id=uu_id_occupant_type_flat_manager,
                    requester=requester,
                )


def run_address_to_building(requester):
    street_uu_id = search_street("Reşat Nuri", requester=requester)

    occupant_type_flat_owner = get_occupants_types(occupant_code="FL-OWN")
    occupant_type_flat_tenant = get_occupants_types(occupant_code="FL-TEN")
    occupant_type_flat_manager = get_occupants_types(occupant_code="BU-MNG")
    occupant_type_flat_resident = get_occupants_types(occupant_code="FL-RES")

    occupant_type_dict = dict(
        occupant_type_flat_owner=occupant_type_flat_owner["data"]["uu_id"],
        occupant_type_flat_tenant=occupant_type_flat_tenant["data"]["uu_id"],
        occupant_type_flat_manager=occupant_type_flat_manager["data"]["uu_id"],
        occupant_type_flat_resident=occupant_type_flat_resident["data"]["uu_id"],
    )

    create_post_code(post_code=post_code_dict(street_uu_id), requester=requester)
    selected_post_code_uu_id = list_post_codes(requester=requester)["data"][0]["uu_id"]

    create_addresses(
        address=address_dict(selected_post_code_uu_id), requester=requester
    )
    selected_address_uu_id = list_addresses(requester=requester)["data"][0]["uu_id"]

    build_type_response = list_building_types(type_code="apt")
    build_type_uu_id_ = build_type_response["data"][0]["uu_id"]
    create_build_with_address_uu_id(
        build_dict(
            address_uu_id=selected_address_uu_id,
            build_type_uu_id=build_type_uu_id_,
        ),
        requester=requester,
    )

    selected_build_uu_id = list_building(requester=requester)["data"][0]["uu_id"]
    create_build_parts(build_uu_id=selected_build_uu_id, count=21, requester=requester)

    random_people_list = get_random_people_list(requester=requester)
    building_parts_list = list_building_parts(requester=requester)["data"]
    print("building_parts_list", len(building_parts_list))

    assign_random_people_to_build_parts(
        list_of_random_people=random_people_list,
        list_of_building_parts=building_parts_list,
        occupant_dict=occupant_type_dict,
        build_uu_id=selected_build_uu_id,
        requester=requester,
    )
    print("list_build_living_space", list_build_living_space(requester=requester))
