//
//  Database+Trips.m
//  DrivoMeter
//
//

#import "Database+Trips.h"
#import "Database+Odometer.h"
#import "Trip.h"
#import "Constants.h"
#import "Period.h"

@implementation Database (Trips)

- (Trip *)startCurrentTrip {
  Trip *trip = [Trip insertInManagedObjectContext:self.managedObjectContext];
  [trip setBeginDate:[NSDate date]];
  [trip setBeginStateValue:[self newestOdometerState]];
  [self saveContext];
  return trip;
}

- (void)endTrip:(Trip *)trip withDistance:(double)distance purpose:(NSString *)purpose {

  if ( distance == 0.0) {
    [self.managedObjectContext deleteObject:trip];
  }
  else {
    [trip setDistanceValue:distance];
    [trip setEndDate:[NSDate date]];
    [trip setEndStateValue:[self newestOdometerState]];
    [trip setPurpose:purpose];
  }  
  [self updateOdometerStateWith:distance];
  [self saveContext];
}

- (void)cancelTrip:(Trip *)trip {
  [self deleteTrip:trip];
}

- (void)addTripWithDistance:(double)dist endState:(double)state isBusiness:(BOOL)business date:(NSDate *)date purpose:(NSString *)purpose favorite:(Favorite *)favorite {
  Trip *trip = [self addTripWithDistance:dist endState:state isBusiness:business date:date purpose:purpose];
  [trip setFavorite:favorite];
  
  [self saveContext];
}

- (Trip *)addTripWithDistance:(double)dist endState:(double)state isBusiness:(BOOL)business date:(NSDate *)date purpose:(NSString *)purpose {
  Trip *trip = [Trip insertInManagedObjectContext:[self managedObjectContext]];
  [trip setDistanceValue:dist];
  [trip setIsBusinessValue:business];
  [trip setBeginDate:date];
  [trip setBeginStateValue:(state - dist)];
  [trip setEndStateValue:state];
  [trip setPurpose:purpose];
  [self updateOdometerStateWith:dist];
  [self saveContext];
  return trip;
}

- (NSArray *)listTripsFrom:(NSDate *)begin to:(NSDate *)end {
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"beginDate >= %@ && beginDate < %@", begin, end];
  NSArray *result = [self listCoreObjectsNamed:@"Trip" withPredicate:predicate];
  MSLog(@">>>>>>>>>>> trips %@", result);
  return result;
}

- (NSFetchedResultsController *)fetchedResultsControllerForAllTrips {
  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Trip" inManagedObjectContext:self.managedObjectContext];
  [fetchRequest setEntity:entity];
  NSSortDescriptor *activeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:NO];
  NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:activeSortDescriptor, nil];
  [fetchRequest setSortDescriptors:sortDescriptors];
  
  NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
                                             initWithFetchRequest:fetchRequest
                                             managedObjectContext:[self managedObjectContext]
                                             sectionNameKeyPath:nil cacheName:nil];
  
  return controller;
}

- (NSFetchedResultsController *)fetchedResultsControllerForTripsInRangeFrom:(NSDate *)begin to:(NSDate *)end {
  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Trip" inManagedObjectContext:self.managedObjectContext];
  [fetchRequest setEntity:entity];
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"beginDate >= %@ && beginDate < %@", begin, end];
  [fetchRequest setPredicate:predicate];
  NSSortDescriptor *activeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"beginDate" ascending:NO];
  NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:activeSortDescriptor, nil];
  [fetchRequest setSortDescriptors:sortDescriptors];
  
  NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
                                            initWithFetchRequest:fetchRequest
                                            managedObjectContext:[self managedObjectContext]
                                            sectionNameKeyPath:nil cacheName:nil];
  
  return controller;
}

- (NSFetchedResultsController *)fetchedResultsControllerForFavorites {
  NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  NSEntityDescription *entity = [NSEntityDescription entityForName:@"Trip" inManagedObjectContext:self.managedObjectContext];
  [fetchRequest setEntity:entity];
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"isFavorite = YES"];
  [fetchRequest setPredicate:predicate];
  NSSortDescriptor *activeSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"purpose" ascending:NO];
  NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:activeSortDescriptor, nil];
  [fetchRequest setSortDescriptors:sortDescriptors];
  
  NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
                                            initWithFetchRequest:fetchRequest
                                            managedObjectContext:[self managedObjectContext]
                                            sectionNameKeyPath:nil cacheName:nil];
  
  return controller;
}

- (void)deleteTrip:(Trip *)trip {
  [self.managedObjectContext deleteObject:trip];
  [self updateOdometerStateWith:(-trip.distanceValue)];
  [self saveContext];
}

- (void)deleteAllTrips {
  NSArray *allTrips = [self listCoreObjectsNamed:@"Trip"];
  for (Trip *trip in allTrips) {
    [self deleteTrip:trip];
  }
}

- (void)updateFetchedResultsController:(NSFetchedResultsController *)controller withPeriod:(Period *)period {
  [controller.fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"beginDate >= %@ && beginDate < %@", period.beginningDate, period.endDate]];
}

@end
