/**
 * Location Tracking Service
 *
 * Handles GPS location updates for en-route and in-progress jobs.
 */

import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';
import { updateLocation } from '../api/jobs';

const LOCATION_TASK_NAME = 'background-location-task';

let activeJobId: number | null = null;

// Define the background task
TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }: any) => {
  if (error) {
    console.error('Background location error:', error);
    return;
  }

  if (data && activeJobId) {
    const { locations } = data;
    const location = locations[0];

    if (location) {
      try {
        await updateLocation(activeJobId, {
          latitude: location.coords.latitude,
          longitude: location.coords.longitude,
          accuracy: location.coords.accuracy,
          heading: location.coords.heading,
          speed: location.coords.speed,
        });
      } catch (error) {
        console.error('Failed to send location update:', error);
      }
    }
  }
});

export async function requestLocationPermissions(): Promise<boolean> {
  const { status: foregroundStatus } = await Location.requestForegroundPermissionsAsync();

  if (foregroundStatus !== 'granted') {
    return false;
  }

  const { status: backgroundStatus } = await Location.requestBackgroundPermissionsAsync();

  return backgroundStatus === 'granted';
}

export async function startLocationTracking(jobId: number): Promise<boolean> {
  const hasPermission = await requestLocationPermissions();

  if (!hasPermission) {
    console.warn('Location permission not granted');
    return false;
  }

  activeJobId = jobId;

  // Check if already tracking
  const isTracking = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME);
  if (isTracking) {
    return true;
  }

  await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
    accuracy: Location.Accuracy.High,
    timeInterval: 30000, // 30 seconds
    distanceInterval: 50, // 50 meters
    deferredUpdatesInterval: 30000,
    deferredUpdatesDistance: 50,
    showsBackgroundLocationIndicator: true,
    foregroundService: {
      notificationTitle: 'SmoothSchedule',
      notificationBody: 'Tracking your location for the current job',
      notificationColor: '#2563eb',
    },
  });

  return true;
}

export async function stopLocationTracking(): Promise<void> {
  activeJobId = null;

  const isTracking = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME);
  if (isTracking) {
    await Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME);
  }
}

export async function getCurrentLocation(): Promise<Location.LocationObject | null> {
  try {
    const { status } = await Location.requestForegroundPermissionsAsync();
    if (status !== 'granted') {
      return null;
    }

    return await Location.getCurrentPositionAsync({
      accuracy: Location.Accuracy.High,
    });
  } catch (error) {
    console.error('Error getting current location:', error);
    return null;
  }
}

export function isTrackingActive(): boolean {
  return activeJobId !== null;
}

export function getActiveJobId(): number | null {
  return activeJobId;
}

// Default export for cleaner imports
const locationService = {
  requestPermissions: requestLocationPermissions,
  startTracking: startLocationTracking,
  stopTracking: stopLocationTracking,
  getCurrentLocation,
  isTracking: async () => {
    return await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME);
  },
  getActiveJobId,
};

export default locationService;
