import apiClient from '../../../shared/services/apiClient';

export interface LoyaltyTier {
  id: number;
  level: 'bronze' | 'silver' | 'gold' | 'platinum';
  name: string;
  description: string;
  min_points: number;
  points_earn_rate: number;
  discount_percentage: number;
  benefits: string;
  icon?: string;
  color?: string;
  is_active?: boolean;
}

export interface UserLoyaltyStatus {
  total_points: number;
  lifetime_points: number;
  available_points: number;
  expired_points: number;
  referral_code: string;
  referral_count: number;
  birthday?: string;
  anniversary_date?: string;
  tier: LoyaltyTier;
  next_tier?: {
    id: number;
    level: string;
    name: string;
    min_points: number;
    points_earn_rate: number;
    discount_percentage: number;
    points_needed: number;
  };
  points_needed_for_next_tier?: number;
  tier_started_date?: string;
}

export interface PointsTransaction {
  id: number;
  transaction_type: 'earned' | 'redeemed' | 'expired' | 'bonus' | 'adjustment';
  source: 'booking' | 'referral' | 'birthday' | 'anniversary' | 'redemption' | 'promotion' | 'manual';
  points: number;
  description: string;
  reference_number?: string;
  expires_at?: string;
  created_at: string;
  booking_id?: number;
}

export interface LoyaltyReward {
  id: number;
  name: string;
  description: string;
  reward_type: 'discount' | 'room_upgrade' | 'amenity' | 'cashback' | 'voucher';
  points_cost: number;
  discount_percentage?: number;
  discount_amount?: number;
  max_discount_amount?: number;
  min_booking_amount?: number;
  icon?: string;
  image?: string;
  is_available: boolean;
  can_afford: boolean;
  stock_remaining?: number;
  stock_quantity?: number;
  redeemed_count?: number;
  applicable_tier_id?: number;
  is_active?: boolean;
  valid_from?: string;
  valid_until?: string;
}

export interface RewardRedemption {
  id: number;
  reward: LoyaltyReward;
  points_used: number;
  status: 'pending' | 'active' | 'used' | 'expired' | 'cancelled';
  code?: string;
  booking_id?: number;
  expires_at?: string;
  used_at?: string;
  created_at: string;
}

export interface Referral {
  id: number;
  referred_user?: {
    id: number;
    name: string;
    email: string;
  };
  referral_code: string;
  status: 'pending' | 'completed' | 'rewarded';
  referrer_points_earned: number;
  referred_points_earned: number;
  completed_at?: string;
  rewarded_at?: string;
  created_at: string;
}

export interface LoyaltyStatusResponse {
  status: string;
  data: UserLoyaltyStatus;
}

export interface PointsHistoryResponse {
  status: string;
  data: {
    transactions: PointsTransaction[];
    pagination: {
      total: number;
      page: number;
      limit: number;
      totalPages: number;
    };
  };
}

export interface RewardsResponse {
  status: string;
  data: {
    rewards: LoyaltyReward[];
    available_points: number;
  };
}

export interface RedemptionsResponse {
  status: string;
  data: {
    redemptions: RewardRedemption[];
  };
}

export interface ReferralsResponse {
  status: string;
  data: {
    referrals: Referral[];
    total_referrals: number;
    total_points_earned: number;
  };
}

const loyaltyService = {
  getMyStatus: async (): Promise<LoyaltyStatusResponse> => {
    const response = await apiClient.get('/api/loyalty/my-status');
    return response.data;
  },

  getPointsHistory: async (
    page: number = 1,
    limit: number = 20,
    transactionType?: string
  ): Promise<PointsHistoryResponse> => {
    const params: { page: number; limit: number } = { page, limit };
    if (transactionType) {
      params.transaction_type = transactionType;
    }
    const response = await apiClient.get('/api/loyalty/points/history', { params });
    return response.data;
  },

  updateMyStatus: async (data: { birthday?: string; anniversary_date?: string }): Promise<{ status: string; message: string }> => {
    const response = await apiClient.put('/api/loyalty/my-status', data);
    return response.data;
  },

  getAvailableRewards: async (): Promise<RewardsResponse> => {
    const response = await apiClient.get('/api/loyalty/rewards');
    return response.data;
  },

  redeemReward: async (rewardId: number, bookingId?: number): Promise<{ status: string; message: string; data: RewardRedemption }> => {
    const response = await apiClient.post('/api/loyalty/rewards/redeem', {
      reward_id: rewardId,
      booking_id: bookingId,
    });
    return response.data;
  },

  getMyRedemptions: async (statusFilter?: string): Promise<RedemptionsResponse> => {
    const params: Record<string, unknown> = {};
    if (statusFilter) {
      params.status_filter = statusFilter;
    }
    const response = await apiClient.get('/api/loyalty/rewards/my-redemptions', { params });
    return response.data;
  },

  applyReferralCode: async (referralCode: string): Promise<{ status: string; message: string }> => {
    const response = await apiClient.post('/api/loyalty/referral/apply', {
      referral_code: referralCode,
    });
    return response.data;
  },

  getMyReferrals: async (): Promise<ReferralsResponse> => {
    const response = await apiClient.get('/api/loyalty/referral/my-referrals');
    return response.data;
  },

  getAllTiers: async (): Promise<{ status: string; data: { tiers: LoyaltyTier[] } }> => {
    const response = await apiClient.get('/api/loyalty/admin/tiers');
    return response.data;
  },

  getUsersLoyaltyStatus: async (
    search?: string,
    tierId?: number,
    page: number = 1,
    limit: number = 20
  ): Promise<{
    status: string;
    data: {
      users: Array<{
        user_id: number;
        user_name: string;
        user_email: string;
        tier: LoyaltyTier;
        total_points: number;
        lifetime_points: number;
        available_points: number;
        referral_count: number;
        tier_started_date?: string;
      }>;
      pagination: {
        total: number;
        page: number;
        limit: number;
        totalPages: number;
      };
    };
  }> => {
    const params: { page: number; limit: number } = { page, limit };
    if (search) params.search = search;
    if (tierId) params.tier_id = tierId;
    const response = await apiClient.get('/api/loyalty/admin/users', { params });
    return response.data;
  },

  // Admin: Get loyalty program status
  getProgramStatus: async (): Promise<{ status: string; data: { enabled: boolean; updated_at?: string; updated_by?: string } }> => {
    const response = await apiClient.get('/api/loyalty/admin/status');
    return response.data;
  },

  // Admin: Update loyalty program status
  updateProgramStatus: async (enabled: boolean): Promise<{ status: string; message: string; data: { enabled: boolean } }> => {
    const response = await apiClient.put('/api/loyalty/admin/status', { enabled });
    return response.data;
  },

  // Admin: Create tier
  createTier: async (tierData: Partial<LoyaltyTier>): Promise<{ status: string; message: string; data: LoyaltyTier }> => {
    const response = await apiClient.post('/api/loyalty/admin/tiers', tierData);
    return response.data;
  },

  // Admin: Update tier
  updateTier: async (tierId: number, tierData: Partial<LoyaltyTier>): Promise<{ status: string; message: string; data: LoyaltyTier }> => {
    const response = await apiClient.put(`/api/loyalty/admin/tiers/${tierId}`, tierData);
    return response.data;
  },

  // Admin: Delete tier
  deleteTier: async (tierId: number): Promise<{ status: string; message: string }> => {
    const response = await apiClient.delete(`/api/loyalty/admin/tiers/${tierId}`);
    return response.data;
  },

  // Admin: Get all rewards (admin view)
  getAllRewardsAdmin: async (): Promise<RewardsResponse> => {
    const response = await apiClient.get('/api/loyalty/admin/rewards');
    return response.data;
  },

  // Admin: Create reward
  createReward: async (rewardData: Partial<LoyaltyReward>): Promise<{ status: string; message: string; data: LoyaltyReward }> => {
    const response = await apiClient.post('/api/loyalty/admin/rewards', rewardData);
    return response.data;
  },

  // Admin: Update reward
  updateReward: async (rewardId: number, rewardData: Partial<LoyaltyReward>): Promise<{ status: string; message: string; data: LoyaltyReward }> => {
    const response = await apiClient.put(`/api/loyalty/admin/rewards/${rewardId}`, rewardData);
    return response.data;
  },

  // Admin: Delete reward
  deleteReward: async (rewardId: number): Promise<{ status: string; message: string }> => {
    const response = await apiClient.delete(`/api/loyalty/admin/rewards/${rewardId}`);
    return response.data;
  },
};

export default loyaltyService;

