import type { AlqoveClient } from '../client';

export type ReturnState =
  | 'requested'
  | 'approved'
  | 'rejected'
  | 'awaiting_shipment'
  | 'in_transit'
  | 'received'
  | 'refunded'
  | 'closed'
  | 'cancelled'
  | 'escalated';

export type ReturnReason =
  | 'damaged'
  | 'wrong_item'
  | 'not_as_described'
  | 'doesnt_fit'
  | 'changed_mind'
  | 'other';

export type ReturnShippingPayer = 'seller' | 'buyer' | 'none';

export type ReturnInitiatedBy = 'buyer' | 'seller';

export interface ReturnItem {
  id: string;
  order_item_id: string;
  quantity: number;
  title_snapshot: string | null;
  price_snapshot: number | null;
}

export interface ReturnEscalation {
  id: string;
  return_id: string;
  escalated_by_user_id: string;
  reason: string;
  state: 'open' | 'resolved';
  resolved_by_admin_id: string | null;
  resolution: string | null;
  action: ReturnAdminAction | null;
  resolved_at: string | null;
  created_at: string;
  updated_at: string;
}

export type ProactiveRefundMode = 'keep-it' | 'ship-back';
export type ReturnAdminAction = 'force_refund' | 'force_close_no_refund' | 'no_action';

export interface ProactiveRefundInput {
  mode: ProactiveRefundMode;
  item_ids: string[];
  amount_cents?: number | null;
  refund_original_shipping?: boolean;
  reason?: ReturnReason | null;
  reason_text?: string | null;
}

export interface AdminResolveReturnInput {
  action: ReturnAdminAction;
  resolution: string;
}

export interface OrderReturn {
  id: string;
  order_id: string;
  initiated_by: ReturnInitiatedBy;
  state: ReturnState;
  reason: ReturnReason;
  reason_text: string | null;
  return_shipping_payer: ReturnShippingPayer;
  restocking_fee_cents: number;
  refund_amount_cents: number | null;
  refund_original_shipping: boolean;
  refund_amount_override_cents: number | null;
  stripe_refund_id: string | null;
  tracking_number: string | null;
  carrier: string | null;
  tracker_id: string | null;
  tracking_url: string | null;
  shipping_label_url: string | null;
  easypost_label_error: string | null;
  items: ReturnItem[];
  approved_at: string | null;
  rejected_at: string | null;
  label_issued_at: string | null;
  in_transit_at: string | null;
  received_at: string | null;
  refunded_at: string | null;
  closed_at: string | null;
  cancelled_at: string | null;
  escalation: ReturnEscalation | null;
  created_at: string;
  updated_at: string;
}

export interface OrderReturnSummary {
  id: string;
  order_id: string;
  state: ReturnState;
  reason: ReturnReason;
  refund_amount_cents: number | null;
  counterparty_name: string | null;
  escalation: { state: 'open' | 'resolved'; reason: string } | null;
  created_at: string;
  updated_at: string;
}

export interface CreateReturnInput {
  reason: ReturnReason;
  reason_text?: string;
  item_ids: string[];
  attachment_ids?: string[];
}

export interface OrderReturnResponse {
  data: OrderReturn;
}

export interface OrderReturnSummaryListResponse {
  data: OrderReturnSummary[];
}

export function createReturnEndpoints(client: AlqoveClient) {
  return {
    /** Seller calls must carry a store; legacy methods below remain for compatibility. */
    forStore(storeId: string) {
      const base = `/v1/stores/${storeId}`;
      return {
        listSeller(params: { state?: ReturnState } = {}) {
          const qs = params.state ? `?state=${encodeURIComponent(params.state)}` : '';
          return client.get<OrderReturnSummaryListResponse>(`${base}/returns${qs}`);
        },
        get: (returnId: string) => client.get<OrderReturnResponse>(`${base}/returns/${returnId}`),
        approve: (returnId: string, restockingFeeCents = 0) => client.post<OrderReturnResponse>(`${base}/returns/${returnId}/approve`, { restocking_fee_cents: restockingFeeCents }),
        reject: (returnId: string, reasonText: string) => client.post<OrderReturnResponse>(`${base}/returns/${returnId}/reject`, { reason_text: reasonText }),
        markReceived: (returnId: string) => client.post<OrderReturnResponse>(`${base}/returns/${returnId}/mark-received`, {}),
        retryLabel: (returnId: string) => client.post<OrderReturnResponse>(`${base}/returns/${returnId}/retry-label`, {}),
        sellerCloseWithoutRefund: (returnId: string, reason: string) => client.post<OrderReturnResponse>(`${base}/returns/${returnId}/seller-close-without-refund`, { reason }),
        proactive: (orderId: string, input: ProactiveRefundInput) => client.post<OrderReturnResponse>(`${base}/orders/${orderId}/returns/proactive`, input),
      };
    },
    request(orderId: string, input: CreateReturnInput) {
      return client.post<OrderReturnResponse>(`/v1/orders/${orderId}/returns`, input);
    },
    get(returnId: string) {
      return client.get<OrderReturnResponse>(`/v1/returns/${returnId}`);
    },
    cancel(returnId: string) {
      return client.post<OrderReturnResponse>(`/v1/returns/${returnId}/cancel`, {});
    },
    approve(returnId: string, restockingFeeCents = 0) {
      return client.post<OrderReturnResponse>(`/v1/returns/${returnId}/approve`, {
        restocking_fee_cents: restockingFeeCents,
      });
    },
    reject(returnId: string, reasonText: string) {
      return client.post<OrderReturnResponse>(`/v1/returns/${returnId}/reject`, {
        reason_text: reasonText,
      });
    },
    markReceived(returnId: string) {
      return client.post<OrderReturnResponse>(`/v1/returns/${returnId}/mark-received`, {});
    },
    retryLabel(returnId: string) {
      return client.post<OrderReturnResponse>(`/v1/returns/${returnId}/retry-label`, {});
    },
    listMine(params: { state?: ReturnState } = {}) {
      const qs = params.state ? `?state=${encodeURIComponent(params.state)}` : '';
      return client.get<OrderReturnSummaryListResponse>(`/v1/me/returns${qs}`);
    },
    listSeller(params: { state?: ReturnState } = {}) {
      const qs = params.state ? `?state=${encodeURIComponent(params.state)}` : '';
      return client.get<OrderReturnSummaryListResponse>(`/v1/seller/returns${qs}`);
    },
    proactive(orderId: string, input: ProactiveRefundInput) {
      return client.post<OrderReturnResponse>(
        `/v1/seller/orders/${orderId}/returns/proactive`,
        input,
      );
    },
    escalate(returnId: string, reason: string) {
      return client.post<{ data: ReturnEscalation }>(
        `/v1/returns/${returnId}/escalate`,
        { reason },
      );
    },
    sellerCloseWithoutRefund(returnId: string, reason: string) {
      return client.post<OrderReturnResponse>(
        `/v1/returns/${returnId}/seller-close-without-refund`,
        { reason },
      );
    },
  };
}

export interface AdminReturnsListInput {
  state?: ReturnState;
  include_resolved?: boolean;
  page?: number;
  per_page?: number;
}

export interface PaginationMeta {
  current_page: number;
  last_page: number;
  per_page: number;
  total: number;
  from: number | null;
  to: number | null;
}

export interface PaginationLinks {
  first: string | null;
  last: string | null;
  prev: string | null;
  next: string | null;
}

export interface PaginatedAdminReturnsResponse {
  data: OrderReturnSummary[];
  meta: PaginationMeta;
  links: PaginationLinks;
}

export interface AdminResolveReturnResponse {
  data: {
    escalation: ReturnEscalation;
    return: OrderReturn;
  };
}

export function createAdminReturnEndpoints(client: AlqoveClient) {
  return {
    list(params: AdminReturnsListInput = {}) {
      const qs = new URLSearchParams();
      if (params.state) qs.set('state', params.state);
      if (params.include_resolved) qs.set('include_resolved', '1');
      if (params.page) qs.set('page', String(params.page));
      if (params.per_page) qs.set('per_page', String(params.per_page));
      const suffix = qs.toString() ? `?${qs.toString()}` : '';
      return client.get<PaginatedAdminReturnsResponse>(`/v1/admin/returns${suffix}`);
    },
    resolve(returnId: string, input: AdminResolveReturnInput) {
      return client.post<AdminResolveReturnResponse>(
        `/v1/admin/returns/${returnId}/resolve`,
        input,
      );
    },
  };
}
