from email.headerregistry import Address
from tokenize import blank_re
from django.shortcuts import render, redirect,reverse
from django.http import HttpResponse
from django.conf import settings
from django.core.files.storage import FileSystemStorage
from django.views.decorators.csrf import csrf_exempt

from django.db.models.functions import TruncDate
from django.db.models import Sum
from datetime import datetime, timedelta

from django.core.mail import send_mail

from .forms import gardens_create
from .models import *
from django.http import HttpResponseRedirect
from .forms import *
from django.views.generic.edit import UpdateView,CreateView
from django.shortcuts import reverse
from django.views import generic
from django.core import serializers

from django.contrib import messages

from django.views.decorators.cache import never_cache

from django.utils import timezone

import traceback

from .functions import *
from .flight_planning_algorithm import *

monthsShortLV = ["Jan", "Feb", "Mar", "Apr", "Mai", "Jūn", "Jūl", "Aug", "Sep", "Okt","Nov", "Dec"]
weekdaysLV = ["Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena", "Svētdiena"]

def navbar_database(request):
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)        
    block = Blocks.objects.filter(garden_id__in = garden).order_by('garden_id')
    return {'gardens': garden, 'blocks': block, 'enterprise' : enterprise}

def change_ml_model(request):
    if not request.user.is_authenticated:
        if not request.user.is_superuser:
            return redirect('/')
    context = navbar_database(request)
    cultivares = Cultivares.objects.all()
    yield_stages = YieldStages.objects.all()
    ml_models = MLModels.objects.all()
    missions = Missions.objects.filter(status = 0)
    context.update({'cultivares': cultivares, 'yield_stages': yield_stages, 'ml_models': ml_models, 'missions': missions})

    return render(request, 'change_ml_model.html', context)

def add_photos_admin(request):
    if not request.user.is_authenticated:
        if not request.user.is_superuser:
            return redirect('/')
    context = navbar_database(request)
    cultivares = Cultivares.objects.all()
    missions = Missions.objects.filter(status = 0)
    context.update({'cultivares': cultivares, 'missions': missions})
    return render(request, 'add_photos_admin.html', context)

@never_cache
def create_garden(request):
    cultivares = Cultivares.objects.all()
    cultivaresJSON = serializers.serialize('json', cultivares)

    if not request.user.is_authenticated:
        return redirect('/')
    
    if request.method == 'POST':
        # print(request.POST)
        newGarden = Gardens.objects.create(enterprise_id = request.user.enterprise_id, name = request.POST['garden_name'], address = request.POST['garden_address'], polygon = json.loads(request.POST['garden_border']))
        blocksJSON = request.POST['blocks']
        blocks = json.loads(blocksJSON)
        for i in range(0,len(blocks)):
            block = blocks[i]
            geoJSON = json.loads(block['blockGeoJSON'])
            newblock = Blocks.objects.create(garden_id = newGarden.id, name = block['block_name'], private_meteostation_id = None, polygon = geoJSON, cultivar_id = block['cultivar'])
        return redirect('/gardens/{0}'.format(newGarden.id))
    
    context = {
    'cultivares' : cultivaresJSON,
    }
    context.update(navbar_database(request))

    return render(request, 'create_garden.html',context)

@never_cache
def create_block(request, garden_id, blocks_id):
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.filter(garden_id__in = garden).order_by('garden_id')

    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(id = blocks_id)
    currentBlockTrees = Trees.objects.filter(block_id = blocks_id)
    currentBlockTreeRows = TreeRow.objects.filter(block_id = blocks_id)
    currentBlockProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)
    currentBlockDroneStations = DroneStations.objects.filter(block_id = blocks_id)
    cultivars = Cultivares.objects.all()

    #JSON

    currentBlockJSON = serializers.serialize('json', [currentBlock])
    currentBlockTreesJSON = serializers.serialize('json', currentBlockTrees)
    currentBlockTreeRowsJSON = serializers.serialize('json', currentBlockTreeRows)
    currentBlockProtectedRegionsJSON = serializers.serialize('json', currentBlockProtectedRegions)
    currentBlockDroneStationsJSON = serializers.serialize('json', currentBlockDroneStations)
    
    enterpriseBreeds = EnterpriseSpecificBreeds.objects.filter(enterprise_id = request.user.enterprise_id, cultivar_id = currentBlock.cultivar_id)

    if request.method == 'POST':
        form = request.POST
        if('tree_row_add' in form):
            treeRow = TreeRow.objects.create(block_id = blocks_id, tree_breed_id = form['breed_id'], coordinates = json.loads(form['tree_row_add']))
            TreeRowGetTrees(treeRow)
        elif('drone_station_lat' in form):
            # check if drone station already exists
            if DroneStations.objects.filter(block_id = blocks_id).exists():
                # if it does, update the coordinates
                station = DroneStations.objects.get(block_id = blocks_id)
                station.latitude = form['drone_station_lat']
                station.longitude = form['drone_station_lon']
                station.save()
            else:
                DroneStations.objects.create(latitude = form['drone_station_lat'], longitude = form['drone_station_lon'], block_id = blocks_id)
        elif('no_flight_zone_add' in form):
            ProtectedRegions.objects.create(garden_id = garden_id, polygon = json.loads(form['no_flight_zone_add']))
        elif('features_to_delete' in form):
            FeatureArray = json.loads(form['features_to_delete'])
            print(FeatureArray)
            for feature in FeatureArray:
                type = feature[1]
                id = feature[0]
                if type == 'TreeRow':
                    TreeRow.objects.get(pk = id).delete()
                elif type == 'ProtectedRegion':
                    ProtectedRegions.objects.get(pk = id).delete()
                elif type == 'DroneStation':
                    DroneStations.objects.get(pk = id).delete()
        elif('features_to_edit' in form):
            FeatureArray = json.loads(form['features_to_edit'])
            for feature in FeatureArray:
                type = feature[1]
                id = feature[0]
                if type == 'TreeRow':
                    TreeRow.objects.filter(pk = id).update(coordinates = json.loads(feature[2]))
                    TreeRowGetTrees(TreeRow.objects.get(pk = id))
                elif type == 'ProtectedRegion':
                    ProtectedRegions.objects.filter(pk = id).update(polygon = json.loads(feature[2]))
                elif type == 'DroneStation':
                    DroneStations.objects.filter(pk = id).update(latitude = feature[2][1], longitude = feature[2][0])
                else:
                    print("Unknown type")

        return redirect('/blocks/{0}/{1}/settings_new'.format(garden_id, blocks_id))


    if not request.user.is_authenticated:
        return redirect('/')
    
    context = {
    'cultivars' : cultivars,
    'gardens': garden,
    'blocks': block,
    'enterprise' : enterprise,
    'enterpriseBreeds' : enterpriseBreeds,
    'currentGarden' : currentGarden,
    'currentBlock' : currentBlock,
    'currentBlockJSON' : currentBlockJSON,
    'currentBlockTrees' : currentBlockTreesJSON,
    'currentBlockTreeRows' : currentBlockTreeRowsJSON,
    'currentBlockProtectedRegions' : currentBlockProtectedRegionsJSON,
    'currentBlockDroneStations' : currentBlockDroneStationsJSON,
    }
    return render(request, 'create_block.html', context)






@never_cache
def monitoring_page(request):
    if not request.user.is_authenticated:
        return redirect('/')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.filter(garden_id__in = garden).order_by('garden_id')
    missions = Missions.objects.filter(block_id__in = block)

    enterprise_flights = Flights.objects.filter(status=1, mission_id__in = missions).order_by('start_date')
   
    for flight in enterprise_flights:
        format_data = "%H:%M:%S"
        flight.day = flight.start_date.day
        flight.weekday = weekdaysLV[flight.start_date.weekday()]
        flight.month = monthsShortLV[flight.start_date.month-1]
        flight.start_date_stfr = flight.start_date.strftime(format_data)
        flight.end_date_stfr = flight.end_date.strftime(format_data)

    # json
    flights_json = []
    for flight in enterprise_flights:
        flight_json = {}
        flight_json['id'] = flight.id
        flight_json['garden'] = flight.mission.block.garden.name
        flight_json['garden_id'] = flight.mission.block.garden.id
        flight_json['block'] = flight.mission.block.name
        flight_json['block_id'] = flight.mission.block.id
        flight_json['start_date'] = flight.start_date.strftime('%Y-%m-%d %H:%M:%S')
        flight_json['end_date'] = flight.end_date.strftime('%Y-%m-%d %H:%M:%S')
        flight_json['status'] = flight.status
        flight_json['mission_id'] = flight.mission_id
        flight_json['day'] = flight.day
        flight_json['weekday'] = flight.weekday
        flight_json['month'] = flight.month
        flight_json['start_date_stfr'] = flight.start_date_stfr
        flight_json['end_date_stfr'] = flight.end_date_stfr
        flight_json['is_autonomous'] = flight.mission.block.is_autonomous
        flight_json['mission'] = flight.mission.name
        flight_json['cultivar_id'] = flight.mission.block.cultivar_id
        flights_json.append(flight_json)
    
    enterprise_flights = sorted(enterprise_flights, key=lambda x: x.start_date)


    import datetime
    if request.method == 'POST':
       form = request.POST
       print(form)
       if('changeTime' in form):
            flight_id = form['flightID']
            flight = Flights.objects.get(pk = flight_id)
            flight.end_date = datetime.datetime.strptime(form['start_date'], "%Y-%m-%dT%H:%M") + (flight.end_date - flight.start_date)
            flight.start_date = form['start_date']
            flight.save()
            return redirect('/monitoring')

    
    # region ApexChart
    year_start = timezone.now().replace(month=1, day=1, hour=0, minute=0, second=0)
    today = timezone.now()

    data = TreeState.objects.filter(tree__block__garden_id__in=garden, last_updated__gte=year_start) \
                            .annotate(date=TruncDate('last_updated')) \
                            .values('date', 'tree__block__cultivar__title', 'yield_stage__title') \
                            .annotate(total_yield=Sum('yields')) \
                            .order_by('tree__block__cultivar__title', 'date')

    num_days = (today - year_start).days + 1
    all_dates = [(year_start + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(num_days)]

    # Initialize chart data structure with zeros for all days
    chart_data = {cultivar: {stage: {'dates': all_dates, 'yields': [0]*num_days}
                             for stage in YieldStages.objects.values_list('title', flat=True)}
                  for cultivar in TreeState.objects.values_list('tree__block__cultivar__title', flat=True).distinct()}

    # Fill actual data from query
    for entry in data:
        cultivar_title = entry['tree__block__cultivar__title']
        yield_stage_title = entry['yield_stage__title']
        date = entry['date'].strftime('%Y-%m-%d')
        total_yield = entry['total_yield']
        index = all_dates.index(date)

        # Set the yield value starting from this date
        if index < len(all_dates) - 1:
            for j in range(index, num_days):
                chart_data[cultivar_title][yield_stage_title]['yields'][j] = total_yield

    # Convert to ApexCharts format
    apexcharts_data = []
    for cultivar, stages in chart_data.items():
        for stage, data in stages.items():
            series_data = [{'x': date, 'y': yield_value} for date, yield_value in zip(data['dates'], data['yields'])]
            apexcharts_data.append({'name': f'{cultivar} - {stage}', 'data': series_data})


    context = { 
        'gardens': garden,
        'blocks': block,
        'enterprise' : enterprise,
        'enterprise_flights' : enterprise_flights,
        'flightsJSON' : json.dumps(flights_json),
        'cultivares' : Cultivares.objects.all(),
        'apexcharts_data': json.dumps(apexcharts_data),
               }
    return render(request, 'monitoring_page.html', context)

# Create your views here.

#
#   GARDENS
#

def get_missions_data(block_id):
    # Get the current year
    current_year = datetime.now().year
    start_of_year = datetime(current_year, 1, 1)

    # Filter missions for the specific block and starting from the beginning of the current year
    missions = Missions.objects.filter(block_id=block_id, date__gte=start_of_year).order_by('date')

    return missions

@never_cache
def main_page(request, garden_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')

    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.filter(garden_id__in = garden).order_by('garden_id')

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    currentGardenTrees = Trees.objects.filter(block__garden_id = garden_id, row_id = None)
    BlockPolygons = Blocks.objects.filter(garden_id = garden_id)
    currentGardenTreeRows = TreeRow.objects.filter(block__garden_id = garden_id)

    try: 
        currentGarden = Gardens.objects.get(pk = garden_id)
    except Gardens.DoesNotExist:
        return render(request, 'no_garden_page.html', {'gardens': garden, 'blocks': block, 'enterprise' : enterprise})

    currentGardenProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)


    json_serializer = serializers.get_serializer("json")()
    TreeData = json_serializer.serialize(currentGardenTrees)
    ProtectedRegionsData = json_serializer.serialize(currentGardenProtectedRegions)
    BlockPolygonsData = json_serializer.serialize(BlockPolygons)
    TreeRowData = json_serializer.serialize(currentGardenTreeRows)

    # region ApexChart
    year_start = timezone.now().replace(month=1, day=1, hour=0, minute=0, second=0)
    today = timezone.now()

    data = TreeState.objects.filter(tree__block__garden_id=garden_id, last_updated__gte=year_start) \
                            .annotate(date=TruncDate('last_updated')) \
                            .values('date', 'tree__block__cultivar__title', 'yield_stage__title') \
                            .annotate(total_yield=Sum('yields')) \
                            .order_by('tree__block__cultivar__title', 'date')

    num_days = (today - year_start).days + 1
    all_dates = [(year_start + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(num_days)]

    # Initialize chart data structure with zeros for all days
    chart_data = {cultivar: {stage: {'dates': all_dates, 'yields': [0]*num_days}
                             for stage in YieldStages.objects.values_list('title', flat=True)}
                  for cultivar in TreeState.objects.values_list('tree__block__cultivar__title', flat=True).distinct()}

    # Fill actual data from query
    for entry in data:
        cultivar_title = entry['tree__block__cultivar__title']
        yield_stage_title = entry['yield_stage__title']
        date = entry['date'].strftime('%Y-%m-%d')
        total_yield = entry['total_yield']
        index = all_dates.index(date)

        # Set the yield value starting from this date
        if index < len(all_dates) - 1:
            for j in range(index, num_days):
                chart_data[cultivar_title][yield_stage_title]['yields'][j] = total_yield

    # Convert to ApexCharts format
    apexcharts_data = []
    for cultivar, stages in chart_data.items():
        for stage, data in stages.items():
            series_data = [{'x': date, 'y': yield_value} for date, yield_value in zip(data['dates'], data['yields'])]
            apexcharts_data.append({'name': f'{cultivar} - {stage}', 'data': series_data})

    
    context = {'gardens': garden,
               'blocks': block, 
               'currentGarden': currentGarden, 
               'currentGardenJSON': json_serializer.serialize([currentGarden]),
               'GardenTrees' : TreeData,
               'GardenRows' : TreeRowData,
               'blockPolygons' : BlockPolygonsData,
               'protectedRegions': ProtectedRegionsData,
               'enterprise' : enterprise,
               'apexcharts_data': json.dumps(apexcharts_data),
               'yield_stages': YieldStages.objects.all(),


               'mapCenter' : findCoordinates(currentGarden.address)}



    return render(request, 'garden_page.html', context)

def fill_dates_with_zeros(dates, yields, full_dates):
    """Ensure all dates are filled with zeros where no data exists."""
    yield_dict = dict(zip(dates, yields))
    filled_yields = [yield_dict.get(date, 0) for date in full_dates]
    return full_dates, filled_yields

@never_cache
def garden_settings(request):

    if not request.user.is_authenticated:
        return redirect('/')

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')

    context = {'gardens': garden,
               'blocks': block,
               'enterprise' : enterprise,
               }
    
    return render(request, 'all_edit_page.html', context)

@never_cache
def gardens_edit(request):
    if not request.user.is_authenticated:
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    for garden in gardens:
        x = garden.id
        garden.blockcount = len(Blocks.objects.filter(garden_id = x))
    
    block = Blocks.objects.order_by('garden_id')
    newGarden_form = gardens_create()

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    if request.method == 'POST':
        upload = gardens_create(request.POST)
        if upload.is_valid():
            input = upload.save(commit=False)
            input.enterprise_id = request.user.enterprise_id
            input.save()
        else:
            form = request.POST
            garden = Gardens.objects.get(pk = form.get('gardenID', '0').strip())
            garden.name = form.get('gardenName', '0').strip()
            garden.address = form.get('gardenAddress', '0').strip()
            garden.save()
        return redirect('/garden/edit')
    return render(request, 'garden_edit_page.html', {'gardens': gardens ,'blocks': block, 'newGarden_form' : newGarden_form, 'blocks': block, 'enterprise' : enterprise,})

@never_cache
def garden_block_edit(request):
    if not request.user.is_authenticated:
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    meteostations = Meteostations.objects.filter(enterprise_id = request.user.enterprise_id)

    context = {
                'gardens': gardens,
                'blocks': block, 
                'enterprise' : enterprise,
                'meteostations' : meteostations,
    }
    if request.method == 'POST':
        form = request.POST
        if('addBlock' in form):
            garden_id =  form.get('gardenID', '0')
            name = form.get('block_name', '0').strip()
            station = form.get('block_station', '0')
            if station == '0':
                Blocks.objects.create(garden_id = garden_id, name = name, private_meteostation_id = None)
            else:
                Blocks.objects.create(garden_id = garden_id, name = name, private_meteostation_id = station)
        elif('editBlock' in form):
            pk = form.get('blockID', '0')
            name = form.get('block_name', '0').strip()
            station = form.get('block_station', '0')
            block = Blocks.objects.get(pk = pk)
            if station == '0':
                block.name = name
                block.private_meteostation_id = None
                block.save()
            else:
                block.name = name
                block.private_meteostation_id = station
                block.save()
        else:
            pk = form.get('blockID', '0')
            block = Blocks.objects.get(pk = pk)
            block.delete()
        return redirect('/gardens/blocks/edit')


    return render(request, 'all_garden_add_block.html', context)

@never_cache
def delete_garden(request, garden_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    garden_id = int(garden_id)
    try:
        garden_sel = Gardens.objects.get(id = garden_id)
    except Gardens.DoesNotExist:
        return redirect(gardens_edit)
    garden_sel.delete()
    return redirect(gardens_edit)

#
#   BLOCKS
#
from django.utils import timezone

@never_cache
def block_page(request,garden_id, blocks_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    import json
    from datetime import datetime, timedelta

    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')

    currentBlockMissions = Missions.objects.filter(block_id = blocks_id)
    # block flights that are gotten from mission objects that have the same block id as the current block
    currentBlockFlights = Flights.objects.filter(mission_id__in = currentBlockMissions)


    currentBlockTreesRows = Trees.objects.filter(block_id = currentBlock.id).exclude(row_id = None)
    currentBlockRow = TreeRow.objects.filter(block_id = currentBlock.id)

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    try:
        currentDroneStation = DroneStations.objects.filter(block_id = currentBlock.id)
    except DroneStations.DoesNotExist:
        currentDroneStation = 0

    currentGardenProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)

    json_serializer = serializers.get_serializer("json")()

    # region ApexChart
    year_start = timezone.now().replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
    today = timezone.now()
    missions = Missions.objects.filter(block_id=blocks_id, generated_date__gte=year_start).order_by('generated_date')
    stages = YieldStages.objects.all().order_by('id')

    # Prepare the dates list from the start of the year to today
    num_days = (today - year_start).days + 1
    dates = [(year_start + timedelta(days=i)).strftime('%Y-%m-%d') for i in range(num_days)]

    chart_data = {}
    for stage in stages:
        stage_data = [0] * num_days 

        for mission in missions:
            mission_date_index = (mission.generated_date.date() - year_start.date()).days
            total_yield = TreeState.objects.filter(mission=mission, yield_stage=stage).aggregate(Sum('yields'))['yields__sum'] or 0

            for i in range(mission_date_index, num_days):
                stage_data[i] = total_yield
        
        chart_data[stage.title] = {
            'dates': dates,
            'yields': stage_data
        }

    apexcharts_data = []
    for stage, data in chart_data.items():
        series_data = [{'x': date, 'y': yield_value} for date, yield_value in zip(data['dates'], data['yields'])]
        apexcharts_data.append({'name': stage, 'data': series_data})
    
    # endregion

    yield_stages = YieldStages.objects.all()


    currentBlockTrees = Trees.objects.filter(block_id = blocks_id, row_id = None)
    TreeData = json_serializer.serialize(currentBlockTrees)

    weatherdata = 0

    if currentBlock.private_meteostation_id != None:
        blockMeteoStation = Meteostations.objects.get(pk = currentBlock.private_meteostation_id)
        if blockMeteoStation.last_forecast == None:
            try:
                    weatherdata = get_weather_data(blockMeteoStation)
                    blockMeteoStation.last_forecast = json.dumps(weatherdata, indent=4, sort_keys=True, default=str)
                    blockMeteoStation.save()
            except Exception as e: print(e)
        else:
            try:
                last_forecast_time = datetime.strptime( json.loads(blockMeteoStation.last_forecast)['time'], '%Y-%m-%d %H:%M:%S')
                now = datetime.now()
                difference = now - last_forecast_time
                if difference > timedelta(minutes=20):
                    try:
                        weatherdata = get_weather_data(blockMeteoStation)
                        blockMeteoStation.last_forecast = json.dumps(weatherdata, indent=4, sort_keys=True, default=str)
                        blockMeteoStation.save()
                    except Exception as e: print(e)
                else:
                    weatherdata = json.loads(blockMeteoStation.last_forecast)
                    weatherdata['time'] = last_forecast_time
            except Exception as e: print(e)


    TreeRowData = json_serializer.serialize(currentBlockRow)

    treerowJSON = json.loads(TreeRowData)
    for i in treerowJSON:
        i['fields']['treeCount'] = len( Trees.objects.filter(block_id = currentBlock.id, row_id = i['pk']))
        sum = 0
        for x in Trees.objects.filter(block_id = currentBlock.id, row_id = i['pk']):
            try:
                state = TreeState.objects.get(tree_id = x.id)
                sum += state.yields
            except:
                continue
        i['fields']['yields'] = sum

    ProtectedRegionsData = json_serializer.serialize(currentGardenProtectedRegions)
    DroneStationData = json_serializer.serialize(currentDroneStation)
    FlightData = json_serializer.serialize(currentBlockFlights)
    TreeDataRow = json_serializer.serialize(currentBlockTreesRows)

    flightDataJSON = json.loads(FlightData)
    for i in flightDataJSON:
        flight = Flights.objects.get(pk = i['pk'])
        i['fields']['url'] = flight.get_absolute_url()
        i['fields']['title'] = "Misijas " + flight.mission.name + " lidojums " + str(flight.plan.sequence_num)

    # last mission data
    last_mission = Missions.objects.filter(block_id = blocks_id).order_by('-closed_date').last()


    context = {'gardens': garden,
               'blocks': block, 
               'currentGarden': currentGarden,
               'currentBlock' : currentBlock,
               'currentBlockJSON': json_serializer.serialize([currentBlock]),
               'currentBlockTreeRowsJSON': TreeRowData,
               'currentBlockDroneStationJSON': DroneStationData,
            'currentBlockProtectedRegionsJSON': ProtectedRegionsData,
               'blockTrees' : TreeData,
               'blockPolygon' : currentBlock.polygon,
               'protectedRegions': ProtectedRegionsData,
               'mapCenter' : findCoordinates(currentGarden.address),
               'droneStation' : DroneStationData,
               'enterprise' : enterprise,
               'weatherData': weatherdata,
               'flights' : json.dumps(flightDataJSON),
               'blockTreeRows' : json.dumps(treerowJSON),
               'blockTreesRows' : TreeDataRow,
               'apexcharts_data': json.dumps(apexcharts_data),
                'yield_stages': YieldStages.objects.all(),
               'yield_stages':yield_stages,
                'last_mission': last_mission,
               }

    return render(request, 'block_page.html', context)

@never_cache
def block_edit(request, garden_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    gardenBlocks = Blocks.objects.filter(garden_id = garden_id)
    gardenProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)
    cultivares = Cultivares.objects.all()
    context = {
        'currentGarden': Gardens.objects.get(pk = garden_id),
        'currentGardenJSON' : serializers.serialize('json', [Gardens.objects.get(pk = garden_id)]),
        'currentGardenBlocksJSON' : serializers.serialize('json', gardenBlocks),
        'protectedRegionsJSON' : serializers.serialize('json', gardenProtectedRegions),
        'cultivares' : cultivares,
        }
    context.update(navbar_database(request))
    
    if request.method == 'POST':
        if ('addBlock' in request.POST):
            block_name = request.POST.get('blockName')
            block_cultivar = request.POST.get('blockCultivar')
            block_coordinates = json.loads(request.POST.get('blockCoordinates'))
            # Create a new block object
            new_block = Blocks.objects.create(garden_id=garden_id, name=block_name, cultivar_id=block_cultivar, polygon=block_coordinates)
            new_block.save()
        elif ('editBlock' in request.POST):
            print(request.POST)
            block_id = request.POST.get('block_id')
            block_name = request.POST.get('blockName')
            block_cultivar = request.POST.get('blockCultivar')
            block = Blocks.objects.get(pk=block_id)
            block.name = block_name
            block.cultivar_id = block_cultivar
            block.save()
        elif ('deleteBlock' in request.POST):
            block_id = request.POST.get('block_id')
            block = Blocks.objects.get(pk=block_id)
            block.delete()
        return redirect('/gardens/blocks/{0}'.format(garden_id))

    return render(request, 'block_edit_page.html', context)

@never_cache
def block_specific_edit(request,garden_id,blocks_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)
    currentBlockTreesNoRows = Trees.objects.filter(block_id = currentBlock.id, row_id = None)
    currentBlockTreesRows = Trees.objects.filter(block_id = currentBlock.id).exclude(row_id = None)
    currentBlockRow = TreeRow.objects.filter(block_id = currentBlock.id)
    currentGardenProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)
    currentBlockDoneMissions = Missions.objects.filter(block_id = blocks_id, status = 1)
    currentBlockMissionTreeStates = TreeState.objects.filter(mission_id__in = currentBlockDoneMissions)
    try:
        currentDroneStation = DroneStations.objects.filter(block_id = currentBlock.id)
    except DroneStations.DoesNotExist:
        currentDroneStation = 0
    meteostations = Meteostations.objects.filter(enterprise_id = request.user.enterprise_id)
    drones = Drones.objects.filter(enterprise_id = request.user.enterprise_id, block_id = None) | Drones.objects.filter(enterprise_id = request.user.enterprise_id, block_id = blocks_id)
    cultivares = Cultivares.objects.all()
    breeds = TreeBreeds.objects.all()
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')
    enterpriseBreeds = EnterpriseSpecificBreeds.objects.filter(enterprise_id = request.user.enterprise_id)

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    json_serializer = serializers.get_serializer("json")()
    TreeData = json_serializer.serialize(currentBlockTreesNoRows)
    TreeRowData = json_serializer.serialize(currentBlockRow)
    TreeDataRow = json_serializer.serialize(currentBlockTreesRows)
    ProtectedRegionsData = json_serializer.serialize(currentGardenProtectedRegions)
    DroneStationData = json_serializer.serialize(currentDroneStation)

    missionData = json_serializer.serialize(currentBlockDoneMissions)
    treeStateData = json_serializer.serialize(currentBlockMissionTreeStates)

    import json

    treerowJSON = json.loads(TreeRowData)
    for i in treerowJSON:
        i['fields']['treeCount'] = len( Trees.objects.filter(block_id = currentBlock.id, row_id = i['pk']))
        sum = 0
        for x in Trees.objects.filter(block_id = currentBlock.id, row_id = i['pk']):
            try:
                state = TreeState.objects.get(tree_id = x.id)
                sum += state.yields
            except:
                continue
        i['fields']['yields'] = sum


    if request.method == 'POST':
        form = request.POST
        if ('newTree' in form):
            tree_title = form.get('cultivare', '0').strip()
            tree_breed = form.get('treeBreed', '0').strip()
            tree_latitude = form.get('latitude', '0').strip().replace(',', '.')
            tree_longitude = form.get('longitude','0').strip().replace(',', '.')
            tree_height = form.get('height','0').strip().replace(',', '.')
            tree_width = form.get('width','0').strip().replace(',', '.')
            Trees.objects.create(breed = tree_breed, latitude = tree_latitude, longitude = tree_longitude, height = tree_height, width = tree_width , cultivares_id = Cultivares.objects.get(title = tree_title).id, block_id = currentBlock.id)
        elif('protectedRegion' in form):
            ProtectedRegions.objects.create(polygon = json.loads(form.get('protectedRegion','0')), garden_id = garden_id)
        elif('droneStation' in form):
            DroneStations.objects.create(latitude = form.get('droneLatitude','0'),longitude = form.get('droneLongitude','0'), block_id = blocks_id)
        elif('editTree' in form):
            primaryKey = form.get('editTree', '0').strip()
            tree_title = form.get('cultivare', '0').strip()
            tree_breed = form.get('treeBreed', '0').strip()
            tree_latitude = form.get('latitude', '0').strip()
            tree_longitude = form.get('longitude','0').strip()
            tree_height = form.get('height','0').strip()
            tree_width = form.get('width','0').strip()
            tree = Trees.objects.get(pk = primaryKey )
            tree.title = tree_title
            tree.breed = tree_breed
            tree.height = tree_height
            tree.width = tree_width
            tree.latitude = tree_latitude
            tree.longitude = tree_longitude
            tree.save()
        elif('editChanges' in form):
            data = form.get('editChanges', '0').strip().replace("},{", "}split{").split("split")
            for x in range(0,len(data)):
                data[x] = json.loads(data[x])
                if ('primaryKey' in data[x]):
                    tree = Trees.objects.get(pk = data[x]['primaryKey'])
                    tree.latitude = data[x]['geometry']['coordinates'][1]
                    tree.longitude = data[x]['geometry']['coordinates'][0]
                    tree.save()
                elif('TreeRowID' in data[x]):
                    treeRow = TreeRow.objects.get(pk = data[x]['TreeRowID'])
                    Trees.objects.filter(row_id = treeRow.id).delete()
                    treeRow.coordinates = data[x]
                    treeRow.save()
                    TreeRowGetTrees(treeRow)
                elif('polygonType' in data[x]):
                    if (data[x]['polygonType'] == 'BlockBorder'):
                        currentBlock.polygon = data[x]
                        currentBlock.save()
                    else:
                        region = ProtectedRegions.objects.get(pk = data[x]['polygonType'])
                        region.polygon = data[x]
                        region.save()
                else: # if its a droneStation
                    station = DroneStations.objects.get(block_id = blocks_id)
                    station.latitude = data[x]['geometry']['coordinates'][1]
                    station.longitude = data[x]['geometry']['coordinates'][0]
                    station.save()
            return HttpResponseRedirect(f"/blocks/{garden_id}/{blocks_id}/settings")
        elif ('deleteChanges' in form):
            data = form.get('deleteChanges', '0').split(',')
            for x in data:
                if (x == "Border"):
                    currentBlock.polygon = None
                    currentBlock.save()
                elif(x == "DroneStation"):
                    station = DroneStations.objects.get(block_id = blocks_id)
                    station.delete()
                elif (x.startswith('ProtectedRegion - ')):
                    temp = x.split(" - ")
                    regionKey = temp[1]
                    region = ProtectedRegions.objects.get(pk = regionKey)
                    region.delete()
                elif (x.startswith('TreeRow - ')):
                    temp = x.split(" - ")
                    rowKey = temp[1]
                    treeRow = TreeRow.objects.get(pk = rowKey)
                    treeRow.delete()
                
                else:
                    tree = Trees.objects.get(pk = x)
                    tree.delete()
        elif('meteostation_change' in form):
            meteoID = form.get('meteostation_change', '0')
            if meteoID == '0':
                currentBlock.private_meteostation_id = None
                currentBlock.save()
            else:
                currentBlock.private_meteostation_id = meteoID
                currentBlock.save()
        elif('drone_change' in form):
            droneID = form.get('drone_change', '0')
            if droneID == '0':
                drone = Drones.objects.get(block_id = blocks_id) 
                drone.block_id = None
                drone.save()
            else:
                try:
                    oldDrone = Drones.objects.get(block_id = blocks_id) 
                    oldDrone.block_id = None
                    oldDrone.save()
                    drone = Drones.objects.get(pk = droneID) 
                    drone.block_id = blocks_id
                    drone.save()
                except Drones.DoesNotExist:
                    drone = Drones.objects.get(pk = droneID) 
                    drone.block_id = blocks_id
                    drone.save()
        elif('newTreeRow' in form):
            print(form)
            treeRowGPS = form.get('newTreeRow', '0')
            breed_id = form.get('enterpriseBreedID', '0')
            row = TreeRow.objects.create(
                block_id = blocks_id,
                tree_breed_id = breed_id,
                coordinates = json.loads(treeRowGPS),
            )
            TreeRowGetTrees(row)
        else:
            print(form)
        return HttpResponseRedirect(f"/blocks/{garden_id}/{blocks_id}/settings")

    context = {'gardens': garden,
               'blocks': block, 
               'currentGarden': currentGarden, 
               'currentBlock': currentBlock, 
               'meteostations' : meteostations,
               'drones' : drones,
               'cultivares': cultivares,
               'breeds': breeds,
               'enterpriseBreeds' : enterpriseBreeds,
               'blockTrees' : TreeData,
               'blockPolygon' : currentBlock.polygon,
               'protectedRegions': ProtectedRegionsData,
               'droneStation' : DroneStationData,
               'enterprise' : enterprise,
               'blockTreeRows' : json.dumps(treerowJSON),
               'blockTreesRows' : TreeDataRow,
               'blockMissions' : missionData,
               'blockMissionTreeStates' : treeStateData,
               'mapCenter' : findCoordinates(currentGarden.address)}
    return render(request, 'block_specific_edit_page.html', context)

@never_cache
def mission_plan_viewer(request,mission_id,plan_id):
    if not request.user.is_authenticated:
        return redirect('/')
    
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    mission = Missions.objects.get(pk = mission_id)
    plan = FlightPlans.objects.get(pk = plan_id)

    currentBlock = Blocks.objects.get(pk = mission.block_id)
    try:
        currentDroneStation = DroneStations.objects.filter(block_id = currentBlock.id)
    except DroneStations.DoesNotExist:
        currentDroneStation = 0


    json_serializer = serializers.get_serializer("json")()

    currentBlockTrees = Trees.objects.filter(block_id = currentBlock.id)

    TreeData = json_serializer.serialize(currentBlockTrees)
    DroneStationData = json_serializer.serialize(currentDroneStation)

    context = {'gardens': garden,
               'blocks': block, 
               'enterprise' : enterprise,
               'mission' : mission,
               'plan' : plan.flight_plan,
               'blockTrees' : TreeData,
               'droneStation' : DroneStationData,
               'blockPolygon' : currentBlock.polygon,
               }


    return render(request, 'mission_plan_page.html', context)

    
@never_cache
def block_flight_plan_edit_unselected(request,garden_id,blocks_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    import json
    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')
    currentBlockTrees = Trees.objects.filter(block_id = currentBlock.id)
    currentGardenProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)
    try:
        currentDroneStation = DroneStations.objects.filter(block_id = currentBlock.id)
    except DroneStations.DoesNotExist:
        currentDroneStation = 0
    planCount = FlightPlans.objects.filter(mission_id = None, block_id = blocks_id).count()
    currentBlockFlightPlans = FlightPlans.objects.filter(mission_id = None, block_id = blocks_id)
    json_serializer = serializers.get_serializer("json")()
    DroneStationData = json_serializer.serialize(currentDroneStation)
    TreeData = json_serializer.serialize(currentBlockTrees)
    ProtectedRegionsData = json_serializer.serialize(currentGardenProtectedRegions)

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    if request.method == 'POST':
        form = request.POST
        if('newPath' in form):
           FlightPlans.objects.create(mission_id = None , sequence_num = planCount + 1, block_id = blocks_id)
        elif('editedPaths' in form):
           plan = FlightPlans.objects.get()
           plan.flight_plan = json.loads(form.get('editedPaths','0'))
           plan.save()
        elif('deletedPaths' in form):
            print(form)
        elif('archivePath' in form):
            import datetime
            mission = Missions.objects.create(name = f"Arhivēta misija - { datetime.date.today() }", block_id = blocks_id, stage_id = 1)
            missionPlans = FlightPlans.objects.filter(mission_id = None, block_id = blocks_id)
            if missionPlans.count() > 0:
                for plan in missionPlans:
                    temp = plan
                    temp.mission_id = mission.id
                    temp.save()
            else:
                mission.delete()
        return HttpResponseRedirect(f"/blocks/{garden_id}/{blocks_id}/flightPlan")
    context = {'gardens': garden,
               'blocks': block, 
               'currentGarden': currentGarden,
               'currentBlock': currentBlock, 
               'blockTrees' : TreeData,
               'blockPolygon' : currentBlock.polygon,
               'protectedRegions': ProtectedRegionsData,
               'droneStation' : DroneStationData,
               'blockPlans' : currentBlockFlightPlans,
               'enterprise' : enterprise,

               'mapCenter' : findCoordinates(currentGarden.address)}
    return render(request, 'flight_plan_page.html', context)

@never_cache
def block_flight_plan_edit_selected(request,garden_id,blocks_id,plan_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    import json
    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')
    currentPlan = FlightPlans.objects.get(pk = plan_id)
    currentBlockTrees = Trees.objects.filter(block_id = currentBlock.id)
    currentGardenProtectedRegions = ProtectedRegions.objects.filter(garden_id = garden_id)

    try:
        currentDroneStation = DroneStations.objects.filter(block_id = currentBlock.id)
    except DroneStations.DoesNotExist:
        currentDroneStation = 0
    planCount = FlightPlans.objects.filter(mission_id = None, block_id = blocks_id).count()
    currentBlockFlightPlans = FlightPlans.objects.filter(mission_id = None, block_id = blocks_id)

    json_serializer = serializers.get_serializer("json")()
    DroneStationData = json_serializer.serialize(currentDroneStation)
    TreeData = json_serializer.serialize(currentBlockTrees)
    ProtectedRegionsData = json_serializer.serialize(currentGardenProtectedRegions)

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    if request.method == 'POST':
        form = request.POST
        if('newPath' in form):
           FlightPlans.objects.create(mission_id = None, sequence_num = planCount + 1, block_id = blocks_id)
        if('addPath' in form):
            plan = FlightPlans.objects.get(pk = plan_id)
            plan.flight_plan = json.loads(form.get('addPath','0'))
            plan.save()
        elif('editPath' in form):
           plan = FlightPlans.objects.get(pk = plan_id)
           plan.flight_plan = json.loads(form.get('editPath','0'))
           plan.save()
        elif('deletePath' in form):
            plan = FlightPlans.objects.get(pk = plan_id)
            plan.flight_plan = None
            plan.save()
        elif('archivePath' in form):
            import datetime
            mission = Missions.objects.create(name = f"Arhivēta misija - { datetime.date.today() }", block_id = blocks_id, stage_id = 1)
            missionPlans = FlightPlans.objects.filter(mission_id = None, block_id = blocks_id)
            if missionPlans.count() > 0:
                for plan in missionPlans:
                    temp = plan
                    temp.mission_id = mission.id
                    temp.save()
            else:
                mission.delete()
        return HttpResponseRedirect(f"/blocks/{garden_id}/{blocks_id}/flightPlan/{plan_id}")
    context = {'gardens': garden,
               'blocks': block, 
               'currentGarden': currentGarden,
               'currentBlock': currentBlock, 
               'blockTrees' : TreeData,
               'blockPolygon' : currentBlock.polygon,
               'protectedRegions': ProtectedRegionsData,
               'droneStation' : DroneStationData,
               'blockPlans' : currentBlockFlightPlans,
               'planID' : plan_id,
               'currentPlan': currentPlan.flight_plan,
               'enterprise' : enterprise,

               'mapCenter' : findCoordinates(currentGarden.address)}
    return render(request, 'flight_plan_page_selected.html', context)

@never_cache
def block_missions_overview_page(request, garden_id,blocks_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)
    
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    missions = Missions.objects.filter(block_id = blocks_id)
    yieldStages = YieldStages.objects.all()
    flightPlans = []
    for mission in missions:
        flightPlans += FlightPlans.objects.filter(mission_id = mission.id)
        completedFlights = 0
        for plan in flightPlans:
            completedFlights += Flights.objects.filter(mission_id = mission.id, plan_id = plan.id, status = 3).count()

        mission.progress = f"{ completedFlights } / { FlightPlans.objects.filter(mission_id = mission.id).count() }"
    
    if request.method == 'POST':
        form = request.POST
        if ('NewMission' in form):
            try:
                if (form.get('mission_obstacle_avoidance') == '0'):
                    obstacle_avoidance = False
                else:
                    obstacle_avoidance = True
                if (form.get('mission_one_side') == '0'):
                    only_sides = False
                else:
                    only_sides = True
                autonomous_flight_time_planning(blocks_id, form.get('mission_name','0'), form.get('mission_yieldStages'), only_sides=only_sides, obstacle_avoidance=obstacle_avoidance, flying_altitude=int(form.get('mission_altitude','0')))
            except Exception as e:
                messages.success(request, f"Misiju nesanāca izveidot! Iemesls: {str(e)}\n")
        elif ('deleteMission' in form):
            mission = Missions.objects.get(pk = form.get('missionID','0'))
            mission.delete()
        return HttpResponseRedirect(f"/blocks/{garden_id}/{blocks_id}/missions")
        
    context = {
        'currentGarden': currentGarden,
        'currentBlock': currentBlock,

        'yieldStages' : yieldStages,
        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
        'missions' : missions,
        'flightPlans' : flightPlans,

    }
    return render(request, 'block_missions_overview.html', context)

@never_cache
def block_specific_mission_overview(request, garden_id, blocks_id, mission_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)
    currentMission = Missions.objects.get(pk = mission_id)
    
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    flightPlans = FlightPlans.objects.filter(mission_id = mission_id)
    for plan in flightPlans:
        try:
            from datetime import datetime
            flight = Flights.objects.get(mission_id = mission_id, plan_id = plan.id)
            format_data = "%d-%m-%y %H:%M:%S"
            if flight.status == 3:
                plan.status = "Izpildīts"
                plan.date = f"{ datetime.strftime(flight.start_date , format_data) } - { datetime.strftime(flight.end_date , format_data) }"
            elif flight.status == 2:
                plan.status = "Progresā"
                plan.date = f"{ datetime.strftime(flight.start_date , format_data) } - { datetime.strftime(flight.end_date , format_data) }"
            else:
                plan.status = "Ieplānots"
                plan.date = f"{ datetime.strftime(flight.start_date , format_data) } - { datetime.strftime(flight.end_date , format_data) }"
        except Flights.DoesNotExist:
            plan.status = "Neizpildīts"
            plan.date = "Nav"
    
    try:
        currentDroneStation = DroneStations.objects.filter(block_id = currentBlock.id)
    except DroneStations.DoesNotExist:
        currentDroneStation = 0
    
    json_serializer = serializers.get_serializer("json")()

    currentBlockTreeRows = TreeRow.objects.filter(block_id = currentBlock.id)
    currentNoFlightZones = ProtectedRegions.objects.filter(garden_id = garden_id)



    DroneStationData = json_serializer.serialize(currentDroneStation)
    PlanData = json_serializer.serialize(flightPlans)
    TreeRowData = json_serializer.serialize(currentBlockTreeRows)
    NoFlightZoneData = json_serializer.serialize(currentNoFlightZones)

    context = {
        'currentGarden': currentGarden,
        'currentBlock': currentBlock,
        'currentMission' : currentMission, 

        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
        'flightPlans' : flightPlans,
        'droneStation' : DroneStationData,
        'blockPolygon' : currentBlock.polygon,
        'flightPlans_JSON' :  PlanData,
        'blockTreeRows' : TreeRowData,
        'noFlightZones' : NoFlightZoneData,
    }

    return render(request, 'block_specific_mission_overview.html', context)


@never_cache
def enterprise_settings(request):

    if not request.user.is_authenticated:
        return redirect('/')

    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    block = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    workers = Users.objects.filter(enterprise_id = request.user.enterprise_id)
    workers = workers.exclude(is_owner = True)

    invitations = TemporaryUser.objects.filter(enterprise_id = request.user.enterprise_id)
    for invite in invitations:
        time = invite.invite_time + timedelta(days=1) - timezone.now()
        # if time is under 1 hour, give minutes else give hours
        if time.days == 0:
            if time.seconds < 3600:
                invite.time_left = f"{time.seconds//60} minūtes"
            else:
                invite.time_left = f"{time.seconds//3600} stundas"


    context = {
                'gardens': garden,
                'blocks': block, 
                'enterprise' : enterprise,
                'workers' : workers,
                'invitations' : invitations,
    }

    if request.method == 'POST':
        if 'enterprise_title' in request.POST:
            form = request.POST
            title = form.get('enterprise_title', '0').strip()
            address = form.get('enterprise_address', '0').strip()
            email = form.get('enterprise_email', '0').strip()
            enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
            enterprise.title = title
            enterprise.address = address 
            enterprise.email = email
            enterprise.save()
            return redirect('/enterprise/settings')
        elif 'worker_name' in request.POST:
            form = request.POST
            name = form.get('worker_name', '0').strip()
            surname = form.get('worker_surname', '0').strip()
            email = form.get('worker_email', '0').strip()
            temp = TemporaryUser.objects.create(enterprise_id = request.user.enterprise_id, name = name, surname = surname, email = email)
            registration_url = f"{settings.ALLOWED_HOSTS[0]}/register/code={temp.code}"
            subject = 'Reģistrācijas kods'
            message = f'Jūsu reģistrācijas saite ir {registration_url}'
            email_from = settings.EMAIL_HOST_USER
            recipient_list = [email, ]
            send_mail(subject, message, email_from, recipient_list)
            return redirect('/enterprise/settings')
        elif 'status' in request.POST:
            form = request.POST
            user = Users.objects.get(pk = form.get('id', '0'))
            user.is_active = not user.is_active
            user.save()
            return redirect('/enterprise/settings')
        else:
            form = request.POST
            invite = TemporaryUser.objects.get(pk = form.get('id', '0'))
            invite.delete()
            return redirect('/enterprise/settings')



    return render(request, 'enterprise_settings.html', context)

@never_cache
def device_edit(request):
    if not request.user.is_authenticated:
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    devices = Devices.objects.filter(enterprise_id = request.user.enterprise_id)

    if request.method == 'POST':
        form = request.POST
        if('addDevice' in form):
            name = form.get('device_name', '0').strip()
            block = form.get('device_block','0')
            if block == '0':
                Devices.objects.create(enterprise_id = request.user.enterprise_id, name = name, block_id = None)
            else:
                Devices.objects.create(enterprise_id = request.user.enterprise_id, name = name, block_id = block)
        elif('editDevice' in form):
            pk = form.get('deviceID', '0')
            name = form.get('device_name', '0').strip()
            block = form.get('device_block','0')
            device = Devices.objects.get(pk = pk)
            device.name = name
            device.block_id = block
            device.save()
        else:
            pk = form.get('deviceID', '0')
            device = Devices.objects.get(pk = pk)
            device.delete()
        return redirect('/devices/edit')
            

    context = {
        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
        'devices' : devices,
    }
    return render(request, 'device_edit.html', context)

@never_cache
def drones_edit(request):
    if not request.user.is_authenticated:
        return redirect('/')
    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    drones = Drones.objects.filter(enterprise_id = request.user.enterprise_id)
    droneModels = DroneModels.objects.all()
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    dronesWithBlocks = Drones.objects.filter(enterprise_id = request.user.enterprise_id).exclude(block_id = None)
    blocksDroneless = Blocks.objects.order_by('garden_id')
    for drone in dronesWithBlocks:
        blocksDroneless = blocksDroneless.exclude(pk = drone.block_id)
        

    if request.method == 'POST':
        form = request.POST
        if('addDrone' in form):
            name = form.get('drone_name', '0').strip()
            model = form.get('drone_model', '0').strip()
            block = form.get('drone_block', '0').strip()
            if block == '0':
                Drones.objects.create(enterprise_id = request.user.enterprise_id, name = name, model_id = model, block_id = None)
            else:
                Drones.objects.create(enterprise_id = request.user.enterprise_id, name = name, model_id = model, block_id = block)
        elif('editDrone' in form):
            name = form.get('drone_name', '0').strip()
            model = form.get('drone_model', '0')
            block = form.get('drone_block', '0').strip()
            if block == '0':
                drone = Drones.objects.get(pk = form.get('droneID', '0'))
                drone.name = name
                drone.model_id = model
                drone.block_id = None
                drone.save()
            else:
                drone = Drones.objects.get(pk = form.get('droneID', '0').strip())
                drone.name = name
                drone.model_id = model
                drone.block_id = block
                drone.save()
        else:
            drone = Drones.objects.get(pk = form.get('droneID', '0'))
            drone.delete()
        return redirect('/drones/edit')
    context = {
                'gardens': garden,
                'blocks': blocks, 
                'enterprise' : enterprise,
                'drones' : drones,
                'droneModels': droneModels,
                'blocksDroneless' : blocksDroneless,
    }

    return render(request, 'drone_edit.html', context)

@never_cache
def MeteoStations_edit(request):
    if not request.user.is_authenticated:
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    meteostations = Meteostations.objects.filter(enterprise_id = request.user.enterprise_id)

    services = Meteoservice.objects.all()

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    if request.method == 'POST':
        form = request.POST
        if('addMeteostation' in form):
            name = form.get('meteostation_name', '0').strip()
            location = form.get('meteostation_location', '0').strip()
            service = form.get('meteostation_service', '0')
            serviceURI = form.get('meteostation_serviceuri', '0').strip()
            Meteostations.objects.create(enterprise_id = request.user.enterprise_id, name = name, location = location, meteoservice_id = service, service_uri = serviceURI)
            return redirect('/meteostations/edit')
        elif('editMeteostation' in form):
            pk = form.get('meteoID', '0')
            name = form.get('meteostation_name', '0').strip()
            location = form.get('meteostation_location', '0').strip()
            service = form.get('meteostation_service', '0')
            serviceURI = form.get('meteostation_serviceuri', '0').strip()
            station = Meteostations.objects.get(pk = pk)
            station.name = name
            station.location = location
            station.meteoservice_id = service
            station.service_uri = serviceURI
            station.save()
            return redirect('/meteostations/edit')
        else:
            pk = form.get('meteoID', '0')
            station = Meteostations.objects.get(pk = pk)
            station.delete()
            return redirect('/meteostations/edit')
            


    context = {
        'meteostations': meteostations,
        'services': services,
        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
    }
    return render(request, 'meteostation_edit.html', context)
@never_cache
def scab_page_block(request, blocks_id, garden_id):
    if not request.user.is_authenticated:
        return redirect('/')
    if not Gardens.objects.filter(id = garden_id, enterprise_id = request.user.enterprise_id).exists():
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    currentGarden = Gardens.objects.get(pk = garden_id)
    currentBlock = Blocks.objects.get(pk = blocks_id)

    blockTrees = Trees.objects.filter(block_id = blocks_id)
    
    for tree in blockTrees:
        try: 
            state = TreeState.objects.filter(tree_id = tree.id).order_by('id').last()
            misija = Missions.objects.get(pk = state.mission_id)
            tree.has_scab = state.has_scab
            tree.probability_scab = state.probability_scab
            tree.mission = misija.name
            tree.yields = state.yields
        except:
            tree.has_Scab = None
            tree.probability_scab = None
            tree.mission = None
            tree.yields = None
    
    context = {
        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
        'trees' : blockTrees,
        'currentBlock' : currentBlock,
        'currentGarden' : currentGarden,
    }
    return render(request, 'block_scab_page.html', context)
@never_cache
def scab_page(request):
    if not request.user.is_authenticated:
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)
    
    usersTrees = Trees.objects.all()
    
    for tree in usersTrees:
        try: 
            state = TreeState.objects.filter(tree_id = tree.id).order_by('id').last()
            misija = Missions.objects.get(pk = state.mission_id)
            tree.has_scab = state.has_scab
            tree.probability_scab = state.probability_scab
            tree.mission = misija.name
            tree.yields = state.yields
        except:
            tree.has_Scab = None
            tree.probability_scab = None
            tree.mission = None
            tree.yields = None
    
    context = {
        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
        'trees' : usersTrees,
    }
    return render(request, 'scab_page.html', context)

@never_cache
def enterprise_tree_breeds(request):
    if not request.user.is_authenticated:
        return redirect('/')
    gardens = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.order_by('garden_id')
    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    cultivares = Cultivares.objects.all()
    TreeBreeds = EnterpriseSpecificBreeds.objects.filter(enterprise_id = enterprise.id)


    if request.method == 'POST':
        form = request.POST
        if('addBreed' in form):
            try:
                yields = form.get('breed_yields', '0').strip().replace(',', '.')
                injection = form.get('breed_injection', '0').strip()
                if len(yields) == 0:
                    yields = None
                if len(injection) == 0:
                    injection = None
                EnterpriseSpecificBreeds.objects.create(
                    title = form.get('breed_name', '0').strip(),
                    cultivar_id = form.get('cultivare', '0').strip(),
                    height = form.get('breed_height', '0').strip().replace(',', '.') ,
                    width = form.get('breed_width', '0').strip().replace(',', '.') ,
                    yields = yields,
                    injection = injection,
                    planting_distance = form.get('breed_planting_distance', '0').strip().replace(',', '.') ,
                    enterprise_id = enterprise.id,
                )
            except:
                messages.success(request, ("Problēma ar datiem, mēģiniet vēlreiz!"))
        elif('editBreed' in form):
            try:
                yields = form.get('breed_yields', '0').strip().replace(',', '.')
                injection = form.get('breed_injection', '0').strip()
                if len(yields) == 0:
                    yields = None
                if len(injection) == 0:
                    injection = None
                breed = EnterpriseSpecificBreeds.objects.get(pk = form.get('breedID', '0').strip())
                breed.title = form.get('breed_name', '0').strip()
                breed.cultivar_id = form.get('cultivare', '0').strip()
                breed.height = form.get('breed_height', '0').strip().replace(',', '.') 
                breed.width = form.get('breed_width', '0').strip().replace(',', '.') 
                breed.yields = yields
                breed.injection = injection
                breed.planting_distance = form.get('breed_planting_distance', '0').strip().replace(',', '.') 
                breed.save()
            except:
                messages.success(request, ("Problēma ar datiem, mēģiniet vēlreiz!"))
        elif('breedID' in form):
            try:
                breed = EnterpriseSpecificBreeds.objects.get(pk = form.get('breedID', '0').strip())
                breed.delete()
            except:
                messages.success(request, ("Problēma ar datiem, mēģiniet vēlreiz!"))
        return redirect('/enterprise/tree_breeds')

    context = {
        'gardens': gardens,
        'blocks': blocks,
        'enterprise' : enterprise,
        'cultivares' : cultivares,
        'TreeBreeds' : TreeBreeds,
    }

    return render(request, 'enterprise_tree_breed_page.html', context)
@never_cache
def calendar(request):
    if not request.user.is_authenticated:
        return redirect('/')

    enterprise = Enterprises.objects.get(pk = request.user.enterprise_id)

    garden = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)
    blocks = Blocks.objects.filter(garden_id__in = garden).order_by('garden_id')

    enterprise_flights = Flights.objects.filter(mission_id__in = Missions.objects.filter(block_id__in = Blocks.objects.filter(garden_id__in = Gardens.objects.filter(enterprise_id = request.user.enterprise_id))))
    json_serializer = serializers.get_serializer("json")()
    enterprise_flightsData = json_serializer.serialize(enterprise_flights)
    block_data = json_serializer.serialize(blocks)
    FlightplansData = json_serializer.serialize(FlightPlans.objects.filter(mission_id__in = Missions.objects.filter(block_id__in = Blocks.objects.filter(garden_id__in = Gardens.objects.filter(enterprise_id = request.user.enterprise_id)))))

    flightDataJSON = json.loads(enterprise_flightsData)
    for i in flightDataJSON:
        flight = Flights.objects.get(pk = i['pk'])
        i['fields']['url'] = flight.get_absolute_url()

    context = {
        'gardens': garden,
        'blocks': blocks,
        'enterprise' : enterprise,
        'flights' : json.dumps(flightDataJSON),
        'blockJSON': block_data,
        'flightplans' : FlightplansData,
               }
    return render(request, 'calendar.html', context)