import type { ApiResponse, PaginatedResponse } from '@alqove/types';
import type { AlqoveClient } from '../client';

export interface AdminDashboardMetrics {
  total_stores: number;
  verified_stores: number;
  active_items: number;
  total_sales_cents: number;
  active_orders: number;
  open_disputes: number;
  overdue_disputes: number;
}

export interface AdminStoreSummary {
  id: string;
  name: string;
  city: string | null;
  state: string | null;
  is_verified: boolean;
  item_count: number;
  total_sales: number | null;
  created_at: string;
}

export interface AdminOrderSummary {
  id: string;
  purchase_id: string;
  store: { id: string; name: string };
  buyer: { first_name: string | null; last_name: string | null };
  status: string;
  subtotal: number;
  shipping_cost: number;
  total: number;
  item_count: number;
  created_at: string;
}

export interface AdminStoresQueryInput {
  q?: string;
  verified?: 'true' | 'false';
  sort?: 'created_desc' | 'created_asc' | 'name_asc' | 'name_desc';
  page?: number;
  per_page?: number;
}

export interface AdminOrdersQueryInput {
  status?:
    | 'all'
    | 'pending'
    | 'processing'
    | 'shipped'
    | 'delivered'
    | 'cancelled'
    | 'refunded';
  store_id?: string;
  sort?: 'created_desc' | 'created_asc' | 'total_desc' | 'total_asc';
  page?: number;
  per_page?: number;
}

export interface AdminDisputeSummary {
  id: string;
  purchase_id: string;
  stripe_dispute_id: string;
  status: string;
  reason: string | null;
  amount_cents: number;
  evidence_due_by: string | null;
  buyer_first_name: string | null;
  buyer_last_name: string | null;
  outcome: string | null;
  decided_at: string | null;
  created_at: string;
}

export interface AdminDisputeDetail extends AdminDisputeSummary {
  decision_justification: string | null;
  purchase: {
    id: string;
    stripe_payment_intent_id: string | null;
    shipping_address: Record<string, unknown>;
    subtotal: number;
    shipping_total: number;
  };
  orders: {
    id: string;
    store: { id: string; name: string };
    status: string;
    subtotal: number;
    shipping_cost: number;
    stripe_transfer_id: string | null;
    transferred_at: string | null;
    transfer_reversed_at: string | null;
    tracking_number: string | null;
    tracking_url: string | null;
    shipped_at: string | null;
  }[];
}

export interface AdjudicateInput {
  outcome: 'submitted_evidence' | 'accepted' | 'resolved';
  justification: string;
  per_order_actions: { order_id: string; reverse_transfer: boolean }[];
}

export interface AdminActivityEntry {
  id: number;
  event: string;
  actor: { id: string; name: string } | null;
  subject: { type: string | null; id: string | null };
  properties: Record<string, unknown>;
  created_at: string;
}

export interface AdminActivityQueryInput {
  causer_id?: string;
  subject_type?: 'Dispute' | 'Order' | 'Store' | 'User' | 'Review' | 'ReviewReport';
  event_prefix?: string;
  from?: string;
  to?: string;
  page?: number;
  per_page?: number;
}

export interface BulkHideReviewsInput {
  review_ids: string[];
  justification: string;
}

export interface BulkHideReviewsSkipped {
  id: string;
  reason: string;
}

export interface BulkHideReviewsResult {
  data: {
    hidden: string[];
    skipped: BulkHideReviewsSkipped[];
  };
}

export interface AdminStoreDetail extends AdminStoreSummary {
  is_suspended: boolean;
  suspended_at: string | null;
  suspension_reason: string | null;
  owner: { id: string; email: string; name: string } | null;
  counters: {
    items_active: number;
    items_draft: number;
    orders_open: number;
    orders_total: number;
    lifetime_revenue_cents: number;
  };
  recent_orders: { id: string; status: string; total: number; created_at: string }[];
  recent_items: { id: string; title: string; price: number; status: string; created_at: string }[];
}

export interface AdminOrderDetail {
  id: string;
  purchase_id: string;
  status: string;
  subtotal: number;
  shipping_cost: number;
  tax_amount: number;
  total: number;
  tracking_number: string | null;
  tracking_url: string | null;
  carrier: string | null;
  ship_by: string | null;
  shipped_at: string | null;
  delivered_at: string | null;
  cancelled_at: string | null;
  cancellation_reason: string | null;
  stripe_transfer_id: string | null;
  transferred_at: string | null;
  stripe_transfer_reversal_id: string | null;
  transfer_reversed_at: string | null;
  stripe_refund_id: string | null;
  store: { id: string; name: string };
  buyer: { first_name: string | null; last_name: string | null };
  items: {
    id: string;
    item_id: string | null;
    title_snapshot: string;
    price_snapshot: number;
    image_url_snapshot: string | null;
  }[];
  purchase: {
    id: string;
    stripe_payment_intent_id: string | null;
    shipping_address: Record<string, unknown>;
  };
  created_at: string;
}

export interface AdminDisputesQueryInput {
  status?:
    | 'needs_response'
    | 'under_review'
    | 'won'
    | 'lost'
    | 'warning_needs_response'
    | 'warning_under_review'
    | 'warning_closed'
    | 'charge_refunded';
  page?: number;
  per_page?: number;
}

function toQuery(params: Record<string, string | number | boolean | undefined>): string {
  const usp = new URLSearchParams();
  for (const [k, v] of Object.entries(params)) {
    if (v === undefined || v === null || v === '') continue;
    usp.set(k, String(v));
  }
  const qs = usp.toString();
  return qs ? `?${qs}` : '';
}

export function createAdminEndpoints(client: AlqoveClient) {
  return {
    dashboardMetrics() {
      return client.get<ApiResponse<AdminDashboardMetrics>>(
        '/v1/admin/dashboard/metrics',
      );
    },
    listStores(params: AdminStoresQueryInput = {}) {
      return client.get<PaginatedResponse<AdminStoreSummary>>(
        `/v1/admin/stores${toQuery({ ...params })}`,
      );
    },
    showStore(storeId: string) {
      return client.get<ApiResponse<AdminStoreDetail>>(`/v1/admin/stores/${storeId}`);
    },
    verifyStore(storeId: string, justification: string) {
      return client.post<ApiResponse<AdminStoreDetail>>(
        `/v1/admin/stores/${storeId}/verify`,
        { justification },
      );
    },
    suspendStore(storeId: string, justification: string) {
      return client.post<ApiResponse<AdminStoreDetail>>(
        `/v1/admin/stores/${storeId}/suspend`,
        { justification },
      );
    },
    unsuspendStore(storeId: string, justification: string) {
      return client.post<ApiResponse<AdminStoreDetail>>(
        `/v1/admin/stores/${storeId}/unsuspend`,
        { justification },
      );
    },
    listOrders(params: AdminOrdersQueryInput = {}) {
      return client.get<PaginatedResponse<AdminOrderSummary>>(
        `/v1/admin/orders${toQuery({ ...params })}`,
      );
    },
    showOrder(orderId: string) {
      return client.get<ApiResponse<AdminOrderDetail>>(
        `/v1/admin/orders/${orderId}`,
      );
    },
    refundOrder(orderId: string, amountCents: number, justification: string) {
      return client.post<ApiResponse<AdminOrderDetail>>(
        `/v1/admin/orders/${orderId}/refund`,
        { amount_cents: amountCents, justification },
      );
    },
    forceCancelOrder(orderId: string, justification: string) {
      return client.post<ApiResponse<AdminOrderDetail>>(
        `/v1/admin/orders/${orderId}/force-cancel`,
        { justification },
      );
    },
    reverseOrderTransfer(orderId: string, justification: string) {
      return client.post<ApiResponse<AdminOrderDetail>>(
        `/v1/admin/orders/${orderId}/reverse-transfer`,
        { justification },
      );
    },
    listDisputes(params: AdminDisputesQueryInput = {}) {
      return client.get<PaginatedResponse<AdminDisputeSummary>>(
        `/v1/admin/disputes${toQuery({ ...params })}`,
      );
    },
    showDispute(purchaseId: string) {
      return client.get<ApiResponse<AdminDisputeDetail>>(
        `/v1/admin/disputes/${purchaseId}`,
      );
    },
    adjudicate(purchaseId: string, body: AdjudicateInput) {
      return client.post<ApiResponse<AdminDisputeDetail>>(
        `/v1/admin/disputes/${purchaseId}/adjudicate`,
        body,
      );
    },
    submitEvidence(purchaseId: string, extraText?: string) {
      return client.post<ApiResponse<AdminDisputeDetail>>(
        `/v1/admin/disputes/${purchaseId}/submit-evidence`,
        extraText ? { extra_text: extraText } : {},
      );
    },
    retryReversal(purchaseId: string, orderId: string, justification: string) {
      return client.post<ApiResponse<{ reversal_id: string }>>(
        `/v1/admin/disputes/${purchaseId}/retry-reversal/${orderId}`,
        { justification },
      );
    },
    listActivity(params: AdminActivityQueryInput = {}) {
      return client.get<PaginatedResponse<AdminActivityEntry>>(
        `/v1/admin/activity${toQuery({ ...params })}`,
      );
    },
    bulkDeleteMessages(messageIds: string[]) {
      return client.post<ApiResponse<{ deleted_count: number; requested_count: number }>>(
        '/v1/admin/messages/bulk-delete',
        { message_ids: messageIds },
      );
    },
    bulkHideReviews(input: BulkHideReviewsInput) {
      return client.post<BulkHideReviewsResult>(
        '/v1/admin/reviews/bulk-hide',
        input,
      );
    },
  };
}
