/**
 * Bookings API
 *
 * Endpoints for managing container bookings
 */

import { get, post, patch, upload } from './client';
import type {
  CreateBookingRequest,
  BookingResponse,
  BookingListResponse,
  SuccessResponse,
} from '@/types/api';

// TODO: These types should be moved to @/types/api.ts
export interface BookingSearchRequest {
  query?: string;
  status?: string;
  originPort?: string;
  destinationPort?: string;
  startDate?: string;
  endDate?: string;
  organizationId?: string;
}

export interface BookingSearchResponse {
  bookings: BookingResponse[];
  total: number;
}

export interface UpdateBookingStatusRequest {
  status: string;
  notes?: string;
}

/**
 * CSV Booking types
 */
export interface CsvBookingResponse {
  id: string;
  bookingId: string;
  carrierName: string;
  carrierEmail: string;
  origin: string;
  destination: string;
  volumeCBM: number;
  weightKG: number;
  palletCount: number;
  priceUSD: number;
  priceEUR: number;
  primaryCurrency: string;
  transitDays: number;
  containerType: string;
  status: 'PENDING_PAYMENT' | 'PENDING_BANK_TRANSFER' | 'PENDING' | 'ACCEPTED' | 'REJECTED' | 'CANCELLED';
  documents: Array<{
    type: string;
    fileName: string;
    url: string;
  }>;
  notes?: string;
  confirmationToken: string;
  emailSentAt?: string;
  acceptedAt?: string;
  rejectedAt?: string;
  createdAt: string;
  updatedAt: string;
  commissionRate?: number;
  commissionAmountEur?: number;
}

export interface CommissionPaymentResponse {
  sessionUrl: string;
  sessionId: string;
  commissionAmountEur: number;
}

export interface CsvBookingListResponse {
  bookings: CsvBookingResponse[]; // Changed from 'items' to match backend response
  total: number;
  page: number;
  limit: number;
  totalPages: number;
}

export interface CsvBookingStatsResponse {
  total: number;
  pending: number;
  accepted: number;
  rejected: number;
}

/**
 * Create a new booking
 * POST /api/v1/bookings
 */
export async function createBooking(data: CreateBookingRequest): Promise<BookingResponse> {
  return post<BookingResponse>('/api/v1/bookings', data);
}

/**
 * Get booking by ID
 * GET /api/v1/bookings/:id
 */
export async function getBooking(id: string): Promise<BookingResponse> {
  return get<BookingResponse>(`/api/v1/bookings/${id}`);
}

/**
 * Get booking by booking number
 * GET /api/v1/bookings/number/:bookingNumber
 */
export async function getBookingByNumber(bookingNumber: string): Promise<BookingResponse> {
  return get<BookingResponse>(`/api/v1/bookings/number/${bookingNumber}`);
}

/**
 * List bookings with pagination
 * GET /api/v1/bookings?page=1&limit=20&status=CONFIRMED&organizationId=xxx
 */
export async function listBookings(params?: {
  page?: number;
  limit?: number;
  status?: string;
  organizationId?: string;
}): Promise<BookingListResponse> {
  const queryParams = new URLSearchParams();
  if (params?.page) queryParams.append('page', params.page.toString());
  if (params?.limit) queryParams.append('limit', params.limit.toString());
  if (params?.status) queryParams.append('status', params.status);
  if (params?.organizationId) queryParams.append('organizationId', params.organizationId);

  const queryString = queryParams.toString();
  return get<BookingListResponse>(`/api/v1/bookings${queryString ? `?${queryString}` : ''}`);
}

/**
 * Fuzzy search bookings
 * GET /api/v1/bookings/search?q=WCM-2024&limit=10
 */
export async function fuzzySearchBookings(params: {
  q: string;
  limit?: number;
}): Promise<BookingSearchResponse> {
  const queryParams = new URLSearchParams();
  queryParams.append('q', params.q);
  if (params.limit) queryParams.append('limit', params.limit.toString());

  return get<BookingSearchResponse>(`/api/v1/bookings/search?${queryParams.toString()}`);
}

/**
 * Advanced search bookings
 * POST /api/v1/bookings/search/advanced
 */
export async function advancedSearchBookings(
  data: BookingSearchRequest
): Promise<BookingSearchResponse> {
  return post<BookingSearchResponse>('/api/v1/bookings/search/advanced', data);
}

/**
 * Export bookings (CSV/PDF)
 * GET /api/v1/bookings/export?format=csv&status=CONFIRMED
 * Returns blob for download
 */
export async function exportBookings(params: {
  format: 'csv' | 'pdf';
  status?: string;
  organizationId?: string;
  startDate?: string;
  endDate?: string;
}): Promise<Blob> {
  const queryParams = new URLSearchParams();
  queryParams.append('format', params.format);
  if (params.status) queryParams.append('status', params.status);
  if (params.organizationId) queryParams.append('organizationId', params.organizationId);
  if (params.startDate) queryParams.append('startDate', params.startDate);
  if (params.endDate) queryParams.append('endDate', params.endDate);

  const response = await fetch(
    `${process.env.NEXT_PUBLIC_API_URL}/api/v1/bookings/export?${queryParams.toString()}`,
    {
      method: 'GET',
      headers: {
        Authorization: `Bearer ${
          typeof window !== 'undefined' ? localStorage.getItem('access_token') : ''
        }`,
      },
    }
  );

  if (!response.ok) {
    throw new Error(`Export failed: ${response.statusText}`);
  }

  return response.blob();
}

/**
 * Update booking status
 * PATCH /api/v1/bookings/:id/status
 */
export async function updateBookingStatus(
  id: string,
  data: UpdateBookingStatusRequest
): Promise<SuccessResponse> {
  return patch<SuccessResponse>(`/api/v1/bookings/${id}/status`, data);
}

// ============================================================================
// CSV BOOKINGS API
// ============================================================================

/**
 * Create a new CSV booking with document uploads
 * POST /api/v1/csv-bookings
 *
 * Uses multipart/form-data for file uploads
 */
export async function createCsvBooking(formData: FormData): Promise<CsvBookingResponse> {
  return upload<CsvBookingResponse>('/api/v1/csv-bookings', formData);
}

/**
 * Get CSV booking by ID
 * GET /api/v1/csv-bookings/:id
 */
export async function getCsvBooking(id: string): Promise<CsvBookingResponse> {
  return get<CsvBookingResponse>(`/api/v1/csv-bookings/${id}`);
}

/**
 * List CSV bookings with pagination and filters
 * GET /api/v1/csv-bookings?page=1&limit=20&status=PENDING
 */
export async function listCsvBookings(params?: {
  page?: number;
  limit?: number;
  status?: 'PENDING' | 'ACCEPTED' | 'REJECTED';
  startDate?: string;
  endDate?: string;
}): Promise<CsvBookingListResponse> {
  const queryParams = new URLSearchParams();
  if (params?.page) queryParams.append('page', params.page.toString());
  if (params?.limit) queryParams.append('limit', params.limit.toString());
  if (params?.status) queryParams.append('status', params.status);
  if (params?.startDate) queryParams.append('startDate', params.startDate);
  if (params?.endDate) queryParams.append('endDate', params.endDate);

  const queryString = queryParams.toString();
  return get<CsvBookingListResponse>(`/api/v1/csv-bookings${queryString ? `?${queryString}` : ''}`);
}

/**
 * Get CSV booking statistics for current user
 * GET /api/v1/csv-bookings/stats
 */
export async function getCsvBookingStats(): Promise<CsvBookingStatsResponse> {
  return get<CsvBookingStatsResponse>('/api/v1/csv-bookings/stats');
}

/**
 * Cancel a pending CSV booking
 * PATCH /api/v1/csv-bookings/:id/cancel
 */
export async function cancelCsvBooking(id: string): Promise<SuccessResponse> {
  return patch<SuccessResponse>(`/api/v1/csv-bookings/${id}/cancel`, {});
}

/**
 * Accept a CSV booking (public endpoint, no auth required)
 * POST /api/v1/csv-bookings/:token/accept
 */
export async function acceptCsvBooking(token: string): Promise<CsvBookingResponse> {
  return post<CsvBookingResponse>(
    `/api/v1/csv-bookings/${token}/accept`,
    {},
    false // includeAuth = false
  );
}

/**
 * Reject a CSV booking with reason (public endpoint, no auth required)
 * POST /api/v1/csv-bookings/:token/reject
 */
export async function rejectCsvBooking(
  token: string,
  reason?: string
): Promise<CsvBookingResponse> {
  return post<CsvBookingResponse>(
    `/api/v1/csv-bookings/${token}/reject`,
    { reason },
    false // includeAuth = false
  );
}

/**
 * Create Stripe Checkout session for commission payment
 * POST /api/v1/csv-bookings/:id/pay
 */
export async function payBookingCommission(bookingId: string): Promise<CommissionPaymentResponse> {
  return post<CommissionPaymentResponse>(`/api/v1/csv-bookings/${bookingId}/pay`, {});
}

/**
 * Confirm commission payment after Stripe redirect
 * POST /api/v1/csv-bookings/:id/confirm-payment
 */
export async function confirmBookingPayment(
  bookingId: string,
  sessionId: string
): Promise<CsvBookingResponse> {
  return post<CsvBookingResponse>(`/api/v1/csv-bookings/${bookingId}/confirm-payment`, {
    sessionId,
  });
}

/**
 * Declare bank transfer — user confirms they have sent the wire transfer
 * POST /api/v1/csv-bookings/:id/declare-transfer
 */
export async function declareBankTransfer(bookingId: string): Promise<CsvBookingResponse> {
  return post<CsvBookingResponse>(`/api/v1/csv-bookings/${bookingId}/declare-transfer`, {});
}
