import apiClient from './client';

export interface TrafficPurchaseInfo {
  id: number;
  traffic_gb: number;
  expires_at: string;
  created_at: string;
  days_remaining: number;
  is_expired: boolean;
}

export interface UserSubscriptionInfo {
  id: number;
  status: string;
  is_trial: boolean;
  start_date: string | null;
  end_date: string | null;
  traffic_limit_gb: number;
  traffic_used_gb: number;
  device_limit: number;
  tariff_id: number | null;
  tariff_name: string | null;
  autopay_enabled: boolean;
  sbp_recurring_status: string | null;
  sbp_recurring_id: number | null;
  is_active: boolean;
  days_remaining: number;
  purchased_traffic_gb: number;
  traffic_purchases: TrafficPurchaseInfo[];
}

export interface UserPromoGroupInfo {
  id: number;
  name: string;
  is_default: boolean;
}

export interface UserListItemSubscription {
  id: number;
  tariff_id: number | null;
  tariff_name: string | null;
  status: string;
  is_trial: boolean;
  end_date: string | null;
  days_remaining: number;
  traffic_used_gb: number;
  traffic_limit_gb: number;
  device_limit: number;
}

export interface UserListItem {
  id: number;
  telegram_id: number;
  username: string | null;
  first_name: string | null;
  last_name: string | null;
  full_name: string;
  status: string;
  balance_kopeks: number;
  balance_rubles: number;
  created_at: string;
  last_activity: string | null;
  has_subscription: boolean;
  subscription_status: string | null;
  subscription_is_trial: boolean;
  subscription_end_date: string | null;
  tariff_id: number | null;
  tariff_name: string | null;
  traffic_used_gb: number;
  traffic_limit_gb: number;
  device_limit: number;
  days_remaining: number;
  promo_group_id: number | null;
  promo_group_name: string | null;
  total_spent_kopeks: number;
  purchase_count: number;
  has_restrictions: boolean;
  restriction_topup: boolean;
  restriction_subscription: boolean;
  subscriptions?: UserListItemSubscription[];
}

export interface UsersListResponse {
  users: UserListItem[];
  total: number;
  offset: number;
  limit: number;
}

export interface UserTransactionItem {
  id: number;
  type: string;
  amount_kopeks: number;
  amount_rubles: number;
  description: string | null;
  payment_method: string | null;
  is_completed: boolean;
  created_at: string;
}

export interface UserReferralInfo {
  referral_code: string;
  referrals_count: number;
  total_earnings_kopeks: number;
  commission_percent: number | null;
  referred_by_id: number | null;
  referred_by_username: string | null;
}

export interface UserDetailResponse {
  id: number;
  telegram_id: number;
  username: string | null;
  first_name: string | null;
  last_name: string | null;
  full_name: string;
  status: string;
  language: string;
  balance_kopeks: number;
  balance_rubles: number;
  email: string | null;
  email_verified: boolean;
  created_at: string;
  updated_at: string | null;
  last_activity: string | null;
  cabinet_last_login: string | null;
  subscription: UserSubscriptionInfo | null;
  subscriptions: UserSubscriptionInfo[];
  promo_group: UserPromoGroupInfo | null;
  referral: UserReferralInfo;
  total_spent_kopeks: number;
  purchase_count: number;
  used_promocodes: number;
  has_had_paid_subscription: boolean;
  lifetime_used_traffic_bytes: number;
  campaign_name: string | null;
  campaign_id: number | null;
  restriction_topup: boolean;
  restriction_subscription: boolean;
  restriction_reason: string | null;
  promo_offer_discount_percent: number;
  promo_offer_discount_source: string | null;
  promo_offer_discount_expires_at: string | null;
  recent_transactions: UserTransactionItem[];
  remnawave_uuid: string | null;
}

export interface UserPanelInfo {
  found: boolean;
  trojan_password: string | null;
  vless_uuid: string | null;
  ss_password: string | null;
  subscription_url: string | null;
  happ_link: string | null;
  used_traffic_bytes: number;
  lifetime_used_traffic_bytes: number;
  traffic_limit_bytes: number;
  first_connected_at: string | null;
  online_at: string | null;
  last_connected_node_uuid: string | null;
  last_connected_node_name: string | null;
}

export interface SubscriptionRequestRecord {
  id: number;
  // Remnawave 2.8.0 renamed this panel field userUuid (uuid) -> userId (number).
  userId: number;
  requestAt: string;
  requestIp: string | null;
  userAgent: string | null;
}

export interface SubscriptionRequestHistory {
  total: number;
  records: SubscriptionRequestRecord[];
}

export interface UserActivityItem {
  type: string;
  subtype: string | null;
  source: string | null;
  title: string | null;
  amount_kopeks: number | null;
  timestamp: string;
  meta: Record<string, unknown> | null;
}

export interface UserActivityResponse {
  items: UserActivityItem[];
  total: number;
  offset: number;
  limit: number;
}

export interface UserNodeUsageItem {
  node_uuid: string;
  node_name: string;
  country_code: string;
  total_bytes: number;
  daily_bytes: number[];
}

export interface UserNodeUsageResponse {
  items: UserNodeUsageItem[];
  categories: string[];
  period_days: number;
}

export interface UsersStatsResponse {
  total_users: number;
  active_users: number;
  blocked_users: number;
  deleted_users: number;
  new_today: number;
  new_week: number;
  new_month: number;
  users_with_subscription: number;
  users_with_active_subscription: number;
  users_with_trial: number;
  users_with_expired_subscription: number;
  total_balance_kopeks: number;
  total_balance_rubles: number;
  avg_balance_kopeks: number;
  active_today: number;
  active_week: number;
  active_month: number;
}

// Available tariffs
export interface PeriodPriceInfo {
  days: number;
  price_kopeks: number;
  price_rubles: number;
}

export interface UserAvailableTariff {
  id: number;
  name: string;
  description: string | null;
  is_active: boolean;
  is_trial_available: boolean;
  traffic_limit_gb: number;
  device_limit: number;
  tier_level: number;
  display_order: number;
  period_prices: PeriodPriceInfo[];
  is_daily: boolean;
  daily_price_kopeks: number;
  custom_days_enabled: boolean;
  price_per_day_kopeks: number;
  min_days: number;
  max_days: number;
  device_price_kopeks: number | null;
  max_device_limit: number | null;
  traffic_topup_enabled: boolean;
  traffic_topup_packages: Record<string, number>;
  max_topup_traffic_gb: number;
  is_available: boolean;
  requires_promo_group: boolean;
}

export interface UserAvailableTariffsResponse {
  user_id: number;
  promo_group_id: number | null;
  promo_group_name: string | null;
  tariffs: UserAvailableTariff[];
  total: number;
  current_tariff_id: number | null;
  current_tariff_name: string | null;
}

// Sync types
export interface PanelUserInfo {
  uuid: string | null;
  short_uuid: string | null;
  username: string | null;
  status: string | null;
  expire_at: string | null;
  traffic_limit_gb: number;
  traffic_used_gb: number;
  device_limit: number;
  subscription_url: string | null;
  active_squads: string[];
}

export interface SyncFromPanelResponse {
  success: boolean;
  message: string;
  panel_user: PanelUserInfo | null;
  changes: Record<string, unknown>;
  errors: string[];
}

export interface SyncToPanelResponse {
  success: boolean;
  message: string;
  action: string;
  panel_uuid: string | null;
  changes: Record<string, unknown>;
  errors: string[];
}

export interface PanelSyncStatusResponse {
  user_id: number;
  telegram_id: number;
  remnawave_uuid: string | null;
  subscription_id: number | null;
  subscription_tariff_name: string | null;
  last_sync: string | null;
  bot_subscription_status: string | null;
  bot_subscription_end_date: string | null;
  bot_traffic_limit_gb: number;
  bot_traffic_used_gb: number;
  bot_device_limit: number;
  bot_squads: string[];
  panel_found: boolean;
  panel_status: string | null;
  panel_expire_at: string | null;
  panel_traffic_limit_gb: number;
  panel_traffic_used_gb: number;
  panel_device_limit: number;
  panel_squads: string[];
  has_differences: boolean;
  differences: string[];
}

// Update types
export interface UpdateBalanceRequest {
  amount_kopeks: number;
  description?: string;
  create_transaction?: boolean;
}

export interface UpdateBalanceResponse {
  success: boolean;
  old_balance_kopeks: number;
  new_balance_kopeks: number;
  message: string;
}

export interface UpdateSubscriptionRequest {
  action:
    | 'extend'
    | 'set_end_date'
    | 'change_tariff'
    | 'set_traffic'
    | 'toggle_autopay'
    | 'cancel'
    | 'activate'
    | 'create'
    | 'add_traffic'
    | 'remove_traffic'
    | 'set_device_limit'
    | 'shorten';
  subscription_id?: number;
  days?: number;
  end_date?: string;
  tariff_id?: number;
  traffic_limit_gb?: number;
  traffic_used_gb?: number;
  autopay_enabled?: boolean;
  is_trial?: boolean;
  device_limit?: number;
  traffic_gb?: number;
  traffic_purchase_id?: number;
}

export interface UpdateSubscriptionResponse {
  success: boolean;
  message: string;
  subscription: UserSubscriptionInfo | null;
}

export interface UpdateUserStatusResponse {
  success: boolean;
  old_status: string;
  new_status: string;
  message: string;
}

export interface UpdateRestrictionsRequest {
  restriction_topup?: boolean;
  restriction_subscription?: boolean;
  restriction_reason?: string;
}

export interface UpdateRestrictionsResponse {
  success: boolean;
  restriction_topup: boolean;
  restriction_subscription: boolean;
  restriction_reason: string | null;
  message: string;
}

export interface SyncFromPanelRequest {
  update_subscription?: boolean;
  update_traffic?: boolean;
  create_if_missing?: boolean;
}

export interface SyncToPanelRequest {
  create_if_missing?: boolean;
  update_status?: boolean;
  update_traffic_limit?: boolean;
  update_expire_date?: boolean;
  update_squads?: boolean;
}

export interface AdminUserGiftItem {
  id: number;
  token: string;
  status: string;
  tariff_name: string | null;
  period_days: number;
  device_limit: number;
  amount_kopeks: number;
  payment_method: string | null;
  gift_recipient_type: string | null;
  gift_recipient_value: string | null;
  gift_message: string | null;
  buyer_user_id: number | null;
  buyer_username: string | null;
  buyer_full_name: string | null;
  receiver_user_id: number | null;
  receiver_username: string | null;
  receiver_full_name: string | null;
  created_at: string | null;
  paid_at: string | null;
  delivered_at: string | null;
}

export interface AdminUserGiftsResponse {
  sent: AdminUserGiftItem[];
  received: AdminUserGiftItem[];
  sent_total: number;
  received_total: number;
}

export const adminUsersApi = {
  // List users
  getUsers: async (
    params: {
      offset?: number;
      limit?: number;
      search?: string;
      email?: string;
      status?: 'active' | 'blocked' | 'deleted';
      subscription_status?: string;
      tariff_id?: string;
      promo_group_id?: number;
      campaign_id?: number;
      partner_id?: number;
      sort_by?:
        | 'created_at'
        | 'balance'
        | 'traffic'
        | 'last_activity'
        | 'total_spent'
        | 'purchase_count';
    } = {},
  ): Promise<UsersListResponse> => {
    const response = await apiClient.get('/cabinet/admin/users', { params });
    return response.data;
  },

  // Get users stats
  getStats: async (): Promise<UsersStatsResponse> => {
    const response = await apiClient.get('/cabinet/admin/users/stats');
    return response.data;
  },

  // Get user detail
  getUser: async (userId: number): Promise<UserDetailResponse> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}`);
    return response.data;
  },

  // Get user by telegram ID
  getUserByTelegram: async (telegramId: number): Promise<UserDetailResponse> => {
    const response = await apiClient.get(`/cabinet/admin/users/by-telegram/${telegramId}`);
    return response.data;
  },

  // Get available tariffs for user
  getAvailableTariffs: async (
    userId: number,
    includeInactive = false,
  ): Promise<UserAvailableTariffsResponse> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/available-tariffs`, {
      params: { include_inactive: includeInactive },
    });
    return response.data;
  },

  // Update balance
  updateBalance: async (
    userId: number,
    data: UpdateBalanceRequest,
  ): Promise<UpdateBalanceResponse> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/balance`, data);
    return response.data;
  },

  // Update subscription
  updateSubscription: async (
    userId: number,
    data: UpdateSubscriptionRequest,
  ): Promise<UpdateSubscriptionResponse> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/subscription`, data);
    return response.data;
  },

  // Cancel a user's SBP (Platega) recurring auto-payment
  cancelSbpRecurring: async (userId: number, subId: number): Promise<{ status: string }> => {
    const response = await apiClient.post(
      `/cabinet/admin/users/${userId}/subscriptions/${subId}/cancel-sbp-recurring`,
    );
    return response.data;
  },

  // Update status
  updateStatus: async (
    userId: number,
    status: 'active' | 'blocked' | 'deleted',
    reason?: string,
  ): Promise<UpdateUserStatusResponse> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/status`, {
      status,
      reason,
    });
    return response.data;
  },

  // Block user
  blockUser: async (userId: number, reason?: string): Promise<UpdateUserStatusResponse> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/block`, null, {
      params: { reason },
    });
    return response.data;
  },

  // Unblock user
  unblockUser: async (userId: number): Promise<UpdateUserStatusResponse> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/unblock`);
    return response.data;
  },

  // Send direct Telegram message to user via bot (parity with bot's admin action)
  sendMessage: async (
    userId: number,
    text: string,
  ): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/send-message`, { text });
    return response.data;
  },

  // Update restrictions
  updateRestrictions: async (
    userId: number,
    data: UpdateRestrictionsRequest,
  ): Promise<UpdateRestrictionsResponse> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/restrictions`, data);
    return response.data;
  },

  // Update promo group
  updatePromoGroup: async (
    userId: number,
    promoGroupId: number | null,
  ): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/promo-group`, {
      promo_group_id: promoGroupId,
    });
    return response.data;
  },

  // Update referral commission
  updateReferralCommission: async (
    userId: number,
    commissionPercent: number | null,
  ): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/referral-commission`, {
      commission_percent: commissionPercent,
    });
    return response.data;
  },

  // Delete user (soft delete, does NOT remove from Remnawave)
  deleteUser: async (
    userId: number,
    softDelete = true,
    reason?: string,
  ): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.delete(`/cabinet/admin/users/${userId}`, {
      data: { soft_delete: softDelete, reason },
    });
    return response.data;
  },

  // Full delete user (removes from bot DB + Remnawave panel)
  fullDeleteUser: async (
    userId: number,
  ): Promise<{
    success: boolean;
    message: string;
    deleted_from_bot: boolean;
    deleted_from_panel: boolean;
    panel_error: string | null;
  }> => {
    const response = await apiClient.delete(`/cabinet/admin/users/${userId}/full`);
    return response.data;
  },

  // Assign a referrer to this user
  assignReferrer: async (
    userId: number,
    referrerId: number,
  ): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/assign-referrer`, {
      referrer_id: referrerId,
    });
    return response.data;
  },

  // Remove this user's referrer
  removeReferrer: async (userId: number): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.delete(`/cabinet/admin/users/${userId}/referrer`);
    return response.data;
  },

  // Remove a specific referral from this user's list
  removeReferral: async (
    userId: number,
    referralUserId: number,
  ): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.delete(
      `/cabinet/admin/users/${userId}/referrals/${referralUserId}`,
    );
    return response.data;
  },

  // Get referrals
  getReferrals: async (userId: number, offset = 0, limit = 50): Promise<UsersListResponse> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/referrals`, {
      params: { offset, limit },
    });
    return response.data;
  },

  // Get transactions
  getTransactions: async (
    userId: number,
    params: {
      offset?: number;
      limit?: number;
      transaction_type?: string;
    } = {},
  ): Promise<{
    transactions: UserTransactionItem[];
    total: number;
    offset: number;
    limit: number;
  }> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/transactions`, { params });
    return response.data;
  },

  // Sync status
  getSyncStatus: async (
    userId: number,
    subscriptionId?: number,
  ): Promise<PanelSyncStatusResponse> => {
    const params = subscriptionId != null ? { subscription_id: subscriptionId } : undefined;
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/sync/status`, { params });
    return response.data;
  },

  // Sync from panel
  syncFromPanel: async (
    userId: number,
    data: SyncFromPanelRequest = {},
    subscriptionId?: number,
  ): Promise<SyncFromPanelResponse> => {
    const params = subscriptionId != null ? { subscription_id: subscriptionId } : undefined;
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/sync/from-panel`, data, {
      params,
    });
    return response.data;
  },

  // Sync to panel
  syncToPanel: async (
    userId: number,
    data: SyncToPanelRequest = {},
    subscriptionId?: number,
  ): Promise<SyncToPanelResponse> => {
    const params = subscriptionId != null ? { subscription_id: subscriptionId } : undefined;
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/sync/to-panel`, data, {
      params,
    });
    return response.data;
  },

  // Reset trial
  resetTrial: async (userId: number): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/reset-trial`);
    return response.data;
  },

  // Reset subscription
  resetSubscription: async (userId: number): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/reset-subscription`);
    return response.data;
  },

  // Disable user
  disableUser: async (userId: number): Promise<{ success: boolean; message: string }> => {
    const response = await apiClient.post(`/cabinet/admin/users/${userId}/disable`);
    return response.data;
  },

  // Get panel info
  getPanelInfo: async (userId: number, subscriptionId?: number): Promise<UserPanelInfo> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/panel-info`, {
      params: subscriptionId != null ? { subscription_id: subscriptionId } : undefined,
    });
    return response.data;
  },

  // Get node usage (always 30 days with daily breakdown)
  getNodeUsage: async (userId: number, subscriptionId?: number): Promise<UserNodeUsageResponse> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/node-usage`, {
      params: subscriptionId != null ? { subscription_id: subscriptionId } : undefined,
    });
    return response.data;
  },

  // Unified activity timeline (bot + cabinet actions)
  getUserActivity: async (
    userId: number,
    offset = 0,
    limit = 25,
    types?: string,
  ): Promise<UserActivityResponse> => {
    const params: Record<string, unknown> = { offset, limit };
    if (types) params.types = types;
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/activity`, { params });
    return response.data;
  },

  // Get subscription request history from Remnawave panel
  getSubscriptionRequestHistory: async (
    userId: number,
    subscriptionId?: number,
    offset = 0,
    limit = 20,
  ): Promise<SubscriptionRequestHistory> => {
    const params: Record<string, unknown> = { offset, limit };
    if (subscriptionId != null) params.subscription_id = subscriptionId;
    const response = await apiClient.get(
      `/cabinet/admin/users/${userId}/subscription-request-history`,
      { params },
    );
    return response.data;
  },

  // Get user devices
  getUserDevices: async (
    userId: number,
    subscriptionId?: number,
  ): Promise<{
    devices: {
      hwid: string;
      platform: string;
      device_model: string;
      created_at: string | null;
      local_name?: string | null;
    }[];
    total: number;
    device_limit: number;
  }> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/devices`, {
      params: subscriptionId != null ? { subscription_id: subscriptionId } : undefined,
    });
    return response.data;
  },

  // Set / clear local device alias on behalf of the user (admin override).
  renameUserDevice: async (
    userId: number,
    hwid: string,
    name: string | null,
  ): Promise<{ hwid: string; local_name: string | null }> => {
    const response = await apiClient.patch(
      `/cabinet/admin/users/${userId}/devices/${encodeURIComponent(hwid)}/name`,
      { name },
    );
    return response.data;
  },

  // Delete single device
  deleteUserDevice: async (
    userId: number,
    hwid: string,
    subscriptionId?: number,
  ): Promise<{ success: boolean; message: string; deleted_hwid: string | null }> => {
    const response = await apiClient.delete(`/cabinet/admin/users/${userId}/devices/${hwid}`, {
      params: subscriptionId != null ? { subscription_id: subscriptionId } : undefined,
    });
    return response.data;
  },

  // Reset all devices
  resetUserDevices: async (
    userId: number,
    subscriptionId?: number,
  ): Promise<{ success: boolean; message: string; deleted_count: number }> => {
    const response = await apiClient.delete(`/cabinet/admin/users/${userId}/devices`, {
      params: subscriptionId != null ? { subscription_id: subscriptionId } : undefined,
    });
    return response.data;
  },

  // Get user gifts
  getUserGifts: async (userId: number): Promise<AdminUserGiftsResponse> => {
    const response = await apiClient.get(`/cabinet/admin/users/${userId}/gifts`);
    return response.data;
  },
};
