"""
Field Mobile Models

Models for tracking field employee activity:
- EventStatusHistory: Audit log for job status changes
- EmployeeLocationUpdate: GPS tracking during en-route/in-progress
"""
from django.db import models
from django.utils import timezone


class EventStatusHistory(models.Model):
    """
    Audit log for event/job status changes.

    Records who changed the status, when, and from what location.
    This model lives in the public schema and references events by ID
    since events are in tenant schemas.
    """
    tenant = models.ForeignKey(
        'core.Tenant',
        on_delete=models.CASCADE,
        related_name='event_status_history',
        help_text="Tenant this status change belongs to"
    )
    event_id = models.IntegerField(
        db_index=True,
        help_text="ID of the Event in tenant schema"
    )
    old_status = models.CharField(
        max_length=20,
        help_text="Previous status before change"
    )
    new_status = models.CharField(
        max_length=20,
        help_text="New status after change"
    )
    changed_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        null=True,
        related_name='status_changes',
        help_text="User who made the status change"
    )
    changed_at = models.DateTimeField(
        auto_now_add=True,
        db_index=True
    )
    notes = models.TextField(
        blank=True,
        help_text="Optional notes about the status change"
    )

    # Location at time of status change (optional)
    latitude = models.DecimalField(
        max_digits=10,
        decimal_places=7,
        null=True,
        blank=True,
        help_text="Latitude where status was changed"
    )
    longitude = models.DecimalField(
        max_digits=10,
        decimal_places=7,
        null=True,
        blank=True,
        help_text="Longitude where status was changed"
    )

    # Source of the change
    source = models.CharField(
        max_length=20,
        default='mobile_app',
        choices=[
            ('mobile_app', 'Mobile App'),
            ('web_app', 'Web App'),
            ('api', 'API'),
            ('system', 'System'),
        ],
        help_text="Where the status change originated"
    )

    class Meta:
        app_label = 'field_mobile'
        ordering = ['-changed_at']
        indexes = [
            models.Index(fields=['tenant', 'event_id']),
            models.Index(fields=['changed_by', '-changed_at']),
        ]
        verbose_name = 'Event Status History'
        verbose_name_plural = 'Event Status Histories'

    def __str__(self):
        return f"Event {self.event_id}: {self.old_status} → {self.new_status}"


class EmployeeLocationUpdate(models.Model):
    """
    Periodic location updates from field employees.

    Stored while an employee is en-route to or working on a job.
    Location tracking automatically stops when job is completed.

    Privacy considerations:
    - Only tracked during active jobs (EN_ROUTE, IN_PROGRESS)
    - Automatically stops when job status changes to COMPLETED/CANCELED
    - Old location data can be purged after a configurable retention period
    """
    tenant = models.ForeignKey(
        'core.Tenant',
        on_delete=models.CASCADE,
        related_name='employee_locations',
        help_text="Tenant this location update belongs to"
    )
    employee = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='location_updates',
        help_text="Employee being tracked"
    )
    event_id = models.IntegerField(
        db_index=True,
        help_text="ID of the active job in tenant schema"
    )

    # Location data
    latitude = models.DecimalField(
        max_digits=10,
        decimal_places=7,
        help_text="GPS latitude"
    )
    longitude = models.DecimalField(
        max_digits=10,
        decimal_places=7,
        help_text="GPS longitude"
    )
    accuracy = models.FloatField(
        null=True,
        blank=True,
        help_text="GPS accuracy in meters"
    )
    altitude = models.FloatField(
        null=True,
        blank=True,
        help_text="Altitude in meters (if available)"
    )
    heading = models.FloatField(
        null=True,
        blank=True,
        help_text="Direction of travel in degrees (0-360)"
    )
    speed = models.FloatField(
        null=True,
        blank=True,
        help_text="Speed in meters per second"
    )

    # Timestamp from device
    timestamp = models.DateTimeField(
        db_index=True,
        help_text="When the location was captured on device"
    )

    # Server timestamp
    created_at = models.DateTimeField(
        auto_now_add=True,
        help_text="When the server received this update"
    )

    # Battery level (useful for understanding tracking reliability)
    battery_level = models.FloatField(
        null=True,
        blank=True,
        help_text="Device battery level (0.0-1.0)"
    )

    class Meta:
        app_label = 'field_mobile'
        ordering = ['-timestamp']
        indexes = [
            models.Index(fields=['tenant', 'event_id', '-timestamp']),
            models.Index(fields=['employee', '-timestamp']),
            models.Index(fields=['tenant', 'employee', 'event_id']),
        ]
        verbose_name = 'Employee Location Update'
        verbose_name_plural = 'Employee Location Updates'

    def __str__(self):
        return f"{self.employee} @ ({self.latitude}, {self.longitude})"

    @classmethod
    def get_latest_for_event(cls, tenant_id, event_id):
        """Get the most recent location update for an event."""
        return cls.objects.filter(
            tenant_id=tenant_id,
            event_id=event_id
        ).order_by('-timestamp').first()

    @classmethod
    def get_route_for_event(cls, tenant_id, event_id, limit=100):
        """
        Get location history for an event (for drawing route on map).

        Returns locations ordered by timestamp ascending (oldest first).
        """
        return list(
            cls.objects.filter(
                tenant_id=tenant_id,
                event_id=event_id
            ).order_by('timestamp')[:limit].values(
                'latitude', 'longitude', 'timestamp', 'accuracy'
            )
        )


class FieldCallLog(models.Model):
    """
    Log of masked calls and SMS between employees and customers.

    Tracks all communication through the proxy number for billing
    and audit purposes.
    """
    class CallType(models.TextChoices):
        VOICE = 'voice', 'Voice Call'
        SMS = 'sms', 'SMS'

    class Direction(models.TextChoices):
        OUTBOUND = 'outbound', 'Employee to Customer'
        INBOUND = 'inbound', 'Customer to Employee'

    class Status(models.TextChoices):
        INITIATED = 'initiated', 'Initiated'
        RINGING = 'ringing', 'Ringing'
        IN_PROGRESS = 'in_progress', 'In Progress'
        COMPLETED = 'completed', 'Completed'
        BUSY = 'busy', 'Busy'
        NO_ANSWER = 'no_answer', 'No Answer'
        FAILED = 'failed', 'Failed'
        CANCELED = 'canceled', 'Canceled'

    tenant = models.ForeignKey(
        'core.Tenant',
        on_delete=models.CASCADE,
        related_name='field_call_logs'
    )
    event_id = models.IntegerField(
        db_index=True,
        help_text="ID of the job this call is associated with"
    )

    # Call metadata
    call_type = models.CharField(
        max_length=10,
        choices=CallType.choices
    )
    direction = models.CharField(
        max_length=10,
        choices=Direction.choices
    )
    status = models.CharField(
        max_length=20,
        choices=Status.choices,
        default=Status.INITIATED
    )

    # Participants
    employee = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        null=True,
        related_name='field_calls'
    )
    customer_phone = models.CharField(
        max_length=20,
        help_text="Customer's phone number (E.164 format)"
    )
    proxy_number = models.CharField(
        max_length=20,
        help_text="Twilio proxy number used"
    )

    # Twilio references
    twilio_call_sid = models.CharField(
        max_length=50,
        blank=True,
        help_text="Twilio Call SID for voice calls"
    )
    twilio_message_sid = models.CharField(
        max_length=50,
        blank=True,
        help_text="Twilio Message SID for SMS"
    )

    # Masked session reference
    masked_session = models.ForeignKey(
        'comms_credits.MaskedSession',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='field_calls'
    )

    # Duration and cost
    duration_seconds = models.IntegerField(
        null=True,
        blank=True,
        help_text="Call duration in seconds (for voice)"
    )
    cost_cents = models.IntegerField(
        default=0,
        help_text="Cost charged to tenant in cents"
    )

    # Timestamps
    initiated_at = models.DateTimeField(auto_now_add=True)
    answered_at = models.DateTimeField(null=True, blank=True)
    ended_at = models.DateTimeField(null=True, blank=True)

    class Meta:
        app_label = 'field_mobile'
        ordering = ['-initiated_at']
        indexes = [
            models.Index(fields=['tenant', 'event_id']),
            models.Index(fields=['employee', '-initiated_at']),
            models.Index(fields=['twilio_call_sid']),
        ]
        verbose_name = 'Field Call Log'
        verbose_name_plural = 'Field Call Logs'

    def __str__(self):
        direction = "→" if self.direction == self.Direction.OUTBOUND else "←"
        return f"{self.call_type}: Employee {direction} Customer ({self.status})"
