//
//  RoutesService.swift
//  RouteTracker
//
//  Created by Mariusz Osowski on 12/08/2019.
//  Copyright © 2019 Mariusz Osowski. All rights reserved.
//

import Foundation
import CoreData
import CoreLocation
import UIKit
import MapKit

class RouteService {
    private init() {}
    
    static func getAllRoutes() -> [Route] {
        let fetchRequest: NSFetchRequest<Route> = Route.fetchRequest()
        
        do {
            return try PersistanceService.context.fetch(fetchRequest).reversed()
        } catch {
            print("Error fetching routes: ", error.localizedDescription)
        }
        
        return []
    }
    
    static func saveRoute(locations: [CLLocation]) {
        guard let firstLocation = locations.first else { return }
        guard let lastLocation = locations.last else { return }
        
        var previousLocation: CLLocation? = nil
        var length: Double = 0
        let route = Route(context: PersistanceService.context)
        
        for location in locations {
            if let previousLocation = previousLocation {
                length += location.distance(from: previousLocation)
            }
            
            let routePoint = Location(context: PersistanceService.context)
            routePoint.copyValues(from: location)
            route.addToLocations(routePoint)
            
            previousLocation = location
        }
        
        route.length = length
        route.startedAt = firstLocation.timestamp as NSDate
        route.endedAt = lastLocation.timestamp as NSDate
        
        createMapSnapshow(locations: locations) { image in
            if let image = image {
                route.thumbnail = image.pngData() as NSData?
            }
            
            PersistanceService.saveContext ()
        }
    }
    
    static func removeRoute(_ route: Route) {
        if let locations = route.locations?.allObjects as? [Location] {
            for location in locations {
                PersistanceService.context.delete(location)
            }
        }
        
        PersistanceService.context.delete(route)
        
        do {
            try PersistanceService.context.save()
        } catch {
            print("Error removing route: ", error.localizedDescription)
        }
    }
    
    static func createMapSnapshow(locations: [CLLocation], onComplete: @escaping (UIImage?) -> () ) {
        let options = MKMapSnapshotter.Options()
        
        let coordinates = locations.map{ $0.coordinate }
        let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
        var rect = polyline.boundingMapRect
        rect = rect.insetBy(dx: rect.width * -0.05, dy: rect.height * -0.05)
        let region = MKCoordinateRegion(rect)
        
        
        options.region = region
        options.size = CGSize(width: 128, height: 128)
        options.scale = UIScreen.main.scale
        options.showsPointsOfInterest = false
        
        let snapshotter = MKMapSnapshotter(options: options)
        
        snapshotter.start() { snapshot, error in
            if let image = snapshot?.drawPolyline(polyline, color: .polylineColor, lineWidth: 5.0) {
                onComplete(image)
            }
            
            onComplete(nil)
        }
    }
}
