package de.sebse.fuplanner.services.canteen.types;

import androidx.annotation.NonNull;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Locale;

public class Canteen implements Serializable, Iterable<Day> {
    private final int id;
    private final String name;
    private final String city;
    private final String address;
    private final double lat;
    private final double lng;
    private SortedListDay list = new SortedListDay();

    Canteen(int id, String name, String city, String address, double lat, double lng) {
        this.id = id;
        this.name = name;
        this.city = city;
        this.address = address;
        this.lat = lat;
        this.lng = lng;
    }

    private Day getDay(Calendar calendar) {
        return this.list.getById(calendar);
    }

    public void addDay(Calendar calendar, boolean isClosed) {
        Day day = new Day(this, calendar, isClosed);
        addDay(day);
    }

    void addDay(@NonNull Day day) {
        if (this.list.contains(day)) return;
        if (!day.isClosed()) {
            this.list.add(day);
        }
        Calendar minDate = Calendar.getInstance();
        minDate.add(Calendar.DAY_OF_YEAR, -1);
        Calendar maxDate = Calendar.getInstance();
        maxDate.add(Calendar.DAY_OF_YEAR, 14);
        for (int i = this.list.size() - 1; i >= 0; i--) {
            Day d = this.list.get(i);
            if (d != null && (d.getCalendar().before(minDate) || d.getCalendar().after(maxDate)))
                this.list.remove(i);
        }
    }

    public void cleanUpDays() {
        SortedListDay newList = new SortedListDay();
        Calendar cal = Calendar.getInstance();
        for (Day day : list) {
            if (Canteen.calendarToKey(day.getCalendar()).compareTo(Canteen.calendarToKey(cal)) >= 0) {
                newList.add(day);
            }
        }
        list = newList;
    }

    public int size() {
        return this.list.size();
    }

    public Day get(int index) {
        return this.list.get(index);
    }

    public void update(Canteen canteen) {
        // remove loaded meals when updating days of a canteen
        this.list = canteen.list;
    }

    @NonNull
    @Override
    public Iterator<Day> iterator() {
        return this.list.iterator();
    }

    public static String calendarToKey(Calendar calendar) {
        int y = calendar.get(Calendar.YEAR);
        int m = calendar.get(Calendar.MONTH)+1;
        int d = calendar.get(Calendar.DAY_OF_MONTH);

        return String.format(Locale.getDefault(), "%4d-%2d-%2d", y, m, d).replace(' ', '0');
    }

    public static Calendar keyToCalendar(String dateString) {
        int y = Integer.parseInt(dateString.substring(0, 4));
        int m = Integer.parseInt(dateString.substring(5, 7))-1;
        int d = Integer.parseInt(dateString.substring(8, 10));
        Calendar cal = Calendar.getInstance();
        cal.set(y, m, d, 0, 0, 0);
        return cal;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getCity() {
        return city;
    }

    public String getAddress() {
        return address;
    }

    public double getLat() {
        return lat;
    }

    public double getLng() {
        return lng;
    }

    @NonNull
    @Override
    public String toString() {
        return id+": "+name+"\n"+list.toString()+"\n";
    }
}
