/**
 * Jobs API
 */

import axios from 'axios';
import apiClient from './client';
import { API_BASE_URL } from '../config/api';
import { getAuthToken, getUserData } from '../services/storage';
import type {
  JobsResponse,
  JobDetail,
  StatusChangeRequest,
  LocationUpdateRequest,
  RouteResponse,
  CallResponse,
  SMSRequest,
  SMSResponse,
  CallHistoryItem,
  JobStatus,
  JobListItem,
  RescheduleRequest,
} from '../types';

// Colors matching web app OwnerScheduler.tsx
// Uses time-based logic for scheduled appointments
export const jobStatusColors: Record<JobStatus, string> = {
  SCHEDULED: '#3b82f6',    // blue - future scheduled (matches web default)
  EN_ROUTE: '#facc15',     // yellow - in transit (matches web in-progress)
  IN_PROGRESS: '#facc15',  // yellow - currently happening (matches web)
  COMPLETED: '#22c55e',    // green - finished (matches web)
  CANCELED: '#9ca3af',     // gray - cancelled (matches web)
  NOSHOW: '#f97316',       // orange - no show (matches web)
  AWAITING_PAYMENT: '#f97316', // orange - awaiting payment
  PAID: '#22c55e',         // green - paid
};

// Returns time-aware color (like web app does for overdue appointments)
export function getJobColor(job: { status: JobStatus; start_time: string; end_time: string }): string {
  const now = new Date();
  const startTime = new Date(job.start_time);
  const endTime = new Date(job.end_time);

  // Terminal statuses have fixed colors
  if (job.status === 'COMPLETED' || job.status === 'PAID') return '#22c55e'; // green
  if (job.status === 'NOSHOW') return '#f97316'; // orange
  if (job.status === 'CANCELED') return '#9ca3af'; // gray

  // For active statuses, check timing
  if (job.status === 'SCHEDULED') {
    if (now > endTime) return '#ef4444'; // red - overdue (past end time)
    if (now >= startTime && now <= endTime) return '#facc15'; // yellow - in progress window
    return '#3b82f6'; // blue - future
  }

  // EN_ROUTE and IN_PROGRESS are active
  return '#facc15'; // yellow
}

export const jobStatusLabels: Record<JobStatus, string> = {
  SCHEDULED: 'Scheduled',
  EN_ROUTE: 'En Route',
  IN_PROGRESS: 'In Progress',
  COMPLETED: 'Completed',
  CANCELED: 'Canceled',
  NOSHOW: 'No Show',
  AWAITING_PAYMENT: 'Awaiting Payment',
  PAID: 'Paid',
};

// Get the API URL for appointments endpoint
// Uses api.lvh.me in dev (resolves to local machine), api.smoothschedule.com in prod
function getAppointmentsApiUrl(): string {
  if (__DEV__) {
    return 'http://api.lvh.me:8000';
  }
  return 'https://api.smoothschedule.com';
}

export async function getJobs(params?: { startDate?: string; endDate?: string }): Promise<JobsResponse> {
  // Use the main appointments endpoint with date range support
  const queryParams: Record<string, string> = {};
  if (params?.startDate) queryParams.start_date = params.startDate;
  if (params?.endDate) queryParams.end_date = params.endDate;

  const token = await getAuthToken();
  const userData = await getUserData();
  const subdomain = userData?.business_subdomain;
  const apiUrl = getAppointmentsApiUrl();

  const response = await axios.get<any[]>(`${apiUrl}/appointments/`, {
    params: queryParams,
    headers: {
      'Content-Type': 'application/json',
      ...(token && { Authorization: `Token ${token}` }),
      ...(subdomain && { 'X-Business-Subdomain': subdomain }),
    },
  });

  // Transform the response to match JobsResponse format
  const jobs: JobListItem[] = response.data.map((apt: any) => {
    // Calculate duration in minutes from start/end times
    const start = new Date(apt.start_time);
    const end = new Date(apt.end_time);
    const durationMinutes = Math.round((end.getTime() - start.getTime()) / 60000);

    return {
      id: apt.id,
      title: apt.title || apt.service_name || 'Appointment',
      start_time: apt.start_time,
      end_time: apt.end_time,
      status: apt.status as JobStatus,
      status_display: jobStatusLabels[apt.status as JobStatus] || apt.status,
      customer_name: apt.customer_name || null,
      address: apt.address || apt.location || null,
      service_name: apt.service_name || null,
      duration_minutes: durationMinutes,
    };
  });

  return {
    jobs,
    count: jobs.length,
  };
}

export async function getJobDetail(jobId: number): Promise<JobDetail> {
  const response = await apiClient.get<JobDetail>(`/jobs/${jobId}/`);
  return response.data;
}

export async function setJobStatus(
  jobId: number,
  data: StatusChangeRequest
): Promise<JobDetail> {
  const response = await apiClient.post<JobDetail>(`/jobs/${jobId}/set_status/`, data);
  return response.data;
}

export async function startEnRoute(
  jobId: number,
  data?: { latitude?: number; longitude?: number }
): Promise<JobDetail> {
  const response = await apiClient.post<JobDetail>(`/jobs/${jobId}/start_en_route/`, data || {});
  return response.data;
}

export async function updateLocation(
  jobId: number,
  data: LocationUpdateRequest
): Promise<{ success: boolean }> {
  const response = await apiClient.post<{ success: boolean }>(
    `/jobs/${jobId}/location_update/`,
    data
  );
  return response.data;
}

export async function getJobRoute(jobId: number): Promise<RouteResponse> {
  const response = await apiClient.get<RouteResponse>(`/jobs/${jobId}/route/`);
  return response.data;
}

export async function callCustomer(jobId: number): Promise<CallResponse> {
  const response = await apiClient.post<CallResponse>(`/jobs/${jobId}/call_customer/`);
  return response.data;
}

export async function sendSMS(jobId: number, data: SMSRequest): Promise<SMSResponse> {
  const response = await apiClient.post<SMSResponse>(`/jobs/${jobId}/send_sms/`, data);
  return response.data;
}

export async function getCallHistory(jobId: number): Promise<CallHistoryItem[]> {
  const response = await apiClient.get<CallHistoryItem[]>(`/jobs/${jobId}/call_history/`);
  return response.data;
}

export async function rescheduleJob(
  jobId: number,
  data: RescheduleRequest
): Promise<{ success: boolean; job: JobDetail }> {
  const response = await apiClient.post<{ success: boolean; job: JobDetail }>(
    `/jobs/${jobId}/reschedule/`,
    data
  );
  return response.data;
}

/**
 * Update an appointment's time via PATCH to /appointments/{id}/
 * Used for drag-and-drop rescheduling on the mobile timeline
 */
export async function updateAppointmentTime(
  appointmentId: number,
  data: { start_time: string; end_time: string }
): Promise<JobListItem> {
  const token = await getAuthToken();
  const userData = await getUserData();
  const subdomain = userData?.business_subdomain;
  const apiUrl = getAppointmentsApiUrl();

  const response = await axios.patch<any>(`${apiUrl}/appointments/${appointmentId}/`, data, {
    headers: {
      'Content-Type': 'application/json',
      ...(token && { Authorization: `Token ${token}` }),
      ...(subdomain && { 'X-Business-Subdomain': subdomain }),
    },
  });

  // Transform response to match JobListItem format
  const apt = response.data;
  const start = new Date(apt.start_time);
  const end = new Date(apt.end_time);
  const durationMinutes = Math.round((end.getTime() - start.getTime()) / 60000);

  return {
    id: apt.id,
    title: apt.title || apt.service_name || 'Appointment',
    start_time: apt.start_time,
    end_time: apt.end_time,
    status: apt.status as JobStatus,
    status_display: jobStatusLabels[apt.status as JobStatus] || apt.status,
    customer_name: apt.customer_name || null,
    address: apt.address || apt.location || null,
    service_name: apt.service_name || null,
    duration_minutes: durationMinutes,
  };
}
