import csv
from pathlib import Path

import right_tree.api.data
from .filters import *
from .utils import get_address_from_coordinates, get_point_from_coordinates


CSV_FILENAME = 'plants.csv'
HEADER_FIELDS = ['Names', 'Growth Form / Max Height (m) / Spacing (m) / Forest Position', 'Moisture Preferences',
                 'Tolerances (Water / Drought / Frost / Salinity)', 'Ecosystem Services', 'Carbon Sequestration Rate', 'Planting Stage']


def get_plant_csv_filepath():
    """ Retrives the filepath for the plant csv file.
    """
    return Path(right_tree.api.data.__file__).resolve().parent / 'resources' / CSV_FILENAME


def get_location_filters(request):
    """ Retrives the selected location data from the request.
    """
    filter_rows = [['LOCATION FILTERS:']]
    coordinates = request.query_params.get('coordinates')

    if coordinates is not None:
        eco_district_layer = ecological_district_coordinate_filter(coordinates).first()
        point = get_point_from_coordinates(coordinates)

        filter_rows.append(['Point coordinates:', point])
        filter_rows.append(
            ['Ecological region:', eco_district_layer.ecologic_1 or ''])
        filter_rows.append(
            ['Ecological district:', eco_district_layer.ecologic_2 or ''])
        filter_rows.append(
            ['Property address:', get_address_from_coordinates(coordinates) or ''])
    else:
        filter_rows.append(["None specified"])

    return filter_rows


def get_soil_filters(request):
    """ Retrives the selected soil type data from the request.
    """
    filter_rows = [['SOIL FILTERS:']]
    soil_variant = request.query_params.get('soilVariant')
    coordinates = request.query_params.get('coordinates')

    if soil_variant is not None and coordinates is not None:
        soil_order_obj = soil_order_coordinate_filter(coordinates).first()

        filter_rows.append(
            ['Soil Order:', f"{soil_order_obj.name or ''} ({soil_order_obj.code or ''})"])
        filter_rows.append(['Soil Variant:', soil_variant])
    else:
        filter_rows.append(["None specified"])

    return filter_rows


def get_site_filters(request):
    """ Retrives the selected site data from the request.
    """
    filter_rows = [['SITE FILTERS:']]

    habitat = request.query_params.get('habitat')
    zone = request.query_params.get('zone')
    if zone is not None and habitat is not None:
        habitat_json = json.loads(habitat)
        zone_json = json.loads(zone)

        filter_rows.append(['Habitat:', habitat_json.get("name", "")])
        filter_rows.append(['Zone Name:', zone_json.get("name", "")])
        filter_rows.append(['Zone Variant:', zone_json.get("variant", "")])
        filter_rows.append(
            ['Zone Refined Variant:', zone_json.get("refined_variant", "")])
    else:
        filter_rows.append(["None specified"])

    return filter_rows


def get_filter_values(request):
    """ Retrives all selected values/filters from the request.
    """
    filter_rows = []

    # Add all the location filters
    filter_rows += get_location_filters(request)
    filter_rows.append([''])

    # Add the soil filters
    filter_rows += get_soil_filters(request)
    filter_rows.append([''])

    # Add the project site filters
    filter_rows += get_site_filters(request)
    filter_rows.append([''])

    return filter_rows


def create_plant_csv_file(request, plant_data):
    """ Constructs a csv file that contains selected filter values and the resulting plant list.
    """
    with open(get_plant_csv_filepath(), 'w', encoding='UTF8') as f:
        writer = csv.writer(f)

        # Write filter/selected values 
        for filter_row in get_filter_values(request):
            writer.writerow(filter_row)

        # Write the plant data
        writer.writerow(HEADER_FIELDS)
        for plant in plant_data:
            plant_data_row = [
                plant.display_name,
                plant.display_growth_form,
                plant.moisture_preferences,
                plant.plant_tolerances,
                plant.ecosystem_services,
                plant.carbon_sequestration,
                plant.stage
            ]

            writer.writerow(plant_data_row)
