import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { 
  UserProfile, 
  Match, 
  Transaction, 
  ChatMessage, 
  LeaderboardEntry, 
} from '../types';
import { initOneSignal, triggerCustomNotification } from '../utils/oneSignalHelper';
import { api } from '../utils/api';

interface ViewState {
  view: string;
  payload?: any;
}

interface AppContextType {
  user: UserProfile;
  matches: Match[];
  transactions: Transaction[];
  chatMessages: ChatMessage[];
  leaderboard: LeaderboardEntry[];
  currentView: string;
  viewPayload: any;
  notifications: number;
  pushView: (view: string, payload?: any) => void;
  popView: () => void;
  updateProfile: (name: string, email: string, phone: string) => void;
  joinMatch: (matchId: string, gameName: string) => Promise<{ success: boolean; error?: string }>;
  depositFunds: (channel: 'bKash' | 'Nagad' | 'Rocket', amount: number, walletNo: string, trxId: string) => void;
  withdrawFunds: (channel: 'bKash' | 'Nagad' | 'Rocket', amount: number, walletNo: string) => Promise<{ success: boolean; error?: string }>;
  sendGiftFunds: (phone: string, amount: number) => Promise<{ success: boolean; error?: string }>;
  submitEvidenceUpload: (matchId: string, roomCode: string, imageSrc: string) => Promise<{ success: boolean }>;
  sendChatMessage: (text: string) => void;
  simulateMatchResult: (matchId: string, status: 'WIN' | 'LOSE') => void;
  adminAddPlayer: (matchId: string) => void;
  adminResetMatches: () => void;
  clearNotifications: () => void;
  adminApproveTransaction: (trxId: string) => void;
  adminCancelTransaction: (trxId: string) => void;
}

const AppContext = createContext<AppContextType | undefined>(undefined);

const mapUser = (u: any): UserProfile => ({
  uid: u.uid,
  name: u.name,
  email: u.email,
  phone: u.phone,
  referralCode: u.referral_code,
  balance: Number(u.balance),
  winningBalance: Number(u.winning_balance),
  matchesPlayed: Number(u.matches_played),
  referralsCount: Number(u.referrals_count),
  totalEarnings: Number(u.total_earnings),
});

const mapMatch = (m: any): Match => ({
  id: m.id,
  title: m.title,
  time: m.time,
  gameName: m.game_name,
  category: m.category,
  winningPrize: Number(m.winning_prize),
  entryFee: Number(m.entry_fee),
  playersJoined: Number(m.players_joined),
  totalPlayersNeeded: Number(m.total_players_needed),
  status: m.status,
  roomCode: m.room_code || undefined,
  winnerName: m.winner_name || undefined,
  userJoinedName: m.user_joined_name || undefined,
});

const mapTx = (t: any): Transaction => ({
  id: t.id,
  type: t.type,
  amount: Number(t.amount),
  date: t.date,
  status: t.status,
  description: t.description,
  paymentChannel: t.payment_channel || undefined,
  accountNo: t.account_no || undefined,
  transactionId: t.transaction_id || undefined,
});

const mapChat = (c: any): ChatMessage => ({
  id: c.id,
  sender: c.sender,
  text: c.text,
  timestamp: c.timestamp,
});

const mapLeaderboard = (l: any): LeaderboardEntry => ({
  rank: Number(l.rank_no),
  name: l.name,
  matchesPlayed: Number(l.matches_played),
  earnings: Number(l.earnings),
  badge: l.badge || undefined,
  isCurrentUser: !!l.isCurrentUser,
});

export const AppProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [history, setHistory] = useState<ViewState[]>([{ view: 'home' }]);
  const currentViewState = history[history.length - 1] || { view: 'home' };
  const [notifications, setNotifications] = useState(1);

  const [user, setUser] = useState<UserProfile>(() => ({
    uid: '5281', name: 'Rahul', email: 'mdrahul123134@gmail.com', phone: '8801405416822',
    referralCode: 'C6480645', balance: 1550, winningBalance: 0, matchesPlayed: 0, referralsCount: 4, totalEarnings: 0,
  }));
  const [matches, setMatches] = useState<Match[]>([]);
  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [chatMessages, setChatMessages] = useState<ChatMessage[]>([]);
  const [leaderboard, setLeaderboard] = useState<LeaderboardEntry[]>([]);

  const refreshUser = useCallback(async () => {
    const res = await api.get('/user');
    if (res.success) setUser(mapUser(res.data));
  }, []);

  const refreshMatches = useCallback(async () => {
    const res = await api.get('/matches');
    if (res.success) setMatches(res.data.map(mapMatch));
  }, []);

  const refreshTransactions = useCallback(async () => {
    const res = await api.get('/transactions');
    if (res.success) setTransactions(res.data.map(mapTx));
  }, []);

  const refreshChat = useCallback(async () => {
    const res = await api.get('/chat');
    if (res.success) setChatMessages(res.data.map(mapChat));
  }, []);

  const refreshLeaderboard = useCallback(async () => {
    const res = await api.get('/leaderboard');
    if (res.success) setLeaderboard(res.data.map(mapLeaderboard));
  }, []);

  // Load initial data
  useEffect(() => {
    initOneSignal();
    refreshUser();
    refreshMatches();
    refreshTransactions();
    refreshChat();
    refreshLeaderboard();
  }, [refreshUser, refreshMatches, refreshTransactions, refreshChat, refreshLeaderboard]);

  const pushView = (view: string, payload?: any) => {
    setHistory(prev => [...prev, { view, payload }]);
  };

  const popView = () => {
    if (history.length > 1) {
      setHistory(prev => prev.slice(0, -1));
    }
  };

  const updateProfile = async (name: string, email: string, phone: string) => {
    const res = await api.put('/user', { name, email, phone });
    if (res.success) setUser(mapUser(res.data));
  };

  const joinMatch = async (matchId: string, inGameName: string): Promise<{ success: boolean; error?: string }> => {
    const res = await api.post('/matches/join', { matchId, gameName: inGameName });
    if (res.success) {
      refreshUser();
      refreshMatches();
      refreshTransactions();
      triggerCustomNotification(
        "ম্যাচ জয়েন সফল হয়েছে! 🎮",
        `আপনি "${res.data.title}" ম্যাচে অংশগ্রহণ করেছেন।`,
        "MATCH"
      );
      return { success: true };
    }
    return { success: false, error: res.error };
  };

  const depositFunds = async (channel: 'bKash' | 'Nagad' | 'Rocket', amount: number, walletNo: string, trxId: string) => {
    await api.post('/deposit', { channel, amount, walletNo, trxId });
    refreshTransactions();
    setNotifications(prev => prev + 1);
    setTimeout(() => {
      refreshUser();
      refreshTransactions();
      triggerCustomNotification(
        "ডিপোজিট সফল হয়েছে! 💰",
        `আপনার ৳${amount} এর ${channel} ডিপোজিট সফলভাবে অনুমোদন করা হয়েছে।`,
        "DEPOSIT"
      );
    }, 12000);
  };

  const withdrawFunds = async (channel: 'bKash' | 'Nagad' | 'Rocket', amount: number, walletNo: string): Promise<{ success: boolean; error?: string }> => {
    const res = await api.post('/withdraw', { channel, amount, walletNo });
    if (res.success) {
      refreshUser();
      refreshTransactions();
      setTimeout(() => {
        refreshTransactions();
        triggerCustomNotification(
          "উইথড্রয়াল সফল হয়েছে! 💸",
          `আপনার ৳${amount} এর ${channel} উইথড্র রিকোয়েস্ট সফলভাবে প্রেরণ করা হয়েছে।`,
          "WITHDRAW"
        );
      }, 15000);
      return { success: true };
    }
    return { success: false, error: res.error };
  };

  const sendGiftFunds = async (phone: string, amount: number): Promise<{ success: boolean; error?: string }> => {
    if (user.balance < amount) {
      return { success: false, error: 'বক্স ট্রান্সফারের জন্য মূল ব্যালেন্স অপর্যাপ্ত!' };
    }
    const res = await api.post('/gift', { phone, amount });
    if (res.success) {
      refreshUser();
      refreshTransactions();
      return { success: true };
    }
    return { success: false, error: res.error };
  };

  const submitEvidenceUpload = async (matchId: string, roomCode: string, imageSrc: string): Promise<{ success: boolean }> => {
    await api.post('/matches/evidence', { matchId, roomCode, imageSrc });
    refreshUser();
    refreshMatches();
    refreshTransactions();
    return { success: true };
  };

  const sendChatMessage = async (text: string) => {
    if (!text.trim()) return;
    await api.post('/chat', { text });
    refreshChat();
  };

  const simulateMatchResult = async (matchId: string, status: 'WIN' | 'LOSE') => {
    await api.post('/admin/simulate', { matchId, status });
    refreshUser();
    refreshMatches();
    refreshTransactions();
  };

  const adminAddPlayer = async (matchId: string) => {
    await api.post('/admin/add-player', { matchId });
    refreshMatches();
  };

  const adminResetMatches = async () => {
    await api.post('/admin/reset');
    refreshUser();
    refreshMatches();
    refreshTransactions();
    refreshChat();
  };

  const adminApproveTransaction = async (trxId: string) => {
    await api.post('/admin/approve-tx', { trxId });
    refreshUser();
    refreshTransactions();
    triggerCustomNotification("ট্রানজেকশন অনুমোদিত হয়েছে ✅", "লেনদেনটি সফলভাবে এপ্রুভ করা হয়েছে।", "SYSTEM");
  };

  const adminCancelTransaction = async (trxId: string) => {
    await api.post('/admin/cancel-tx', { trxId });
    refreshUser();
    refreshTransactions();
    triggerCustomNotification("ট্রানজেকশন বাতিল হয়েছে ❌", "লেনদেনটি বাতিল করা হয়েছে।", "SYSTEM");
  };

  const clearNotifications = () => {
    setNotifications(0);
  };

  return (
    <AppContext.Provider value={{
      user, matches, transactions, chatMessages, leaderboard,
      currentView: currentViewState.view, viewPayload: currentViewState.payload,
      notifications, pushView, popView, updateProfile, joinMatch,
      depositFunds, withdrawFunds, sendGiftFunds, submitEvidenceUpload,
      sendChatMessage, simulateMatchResult, adminAddPlayer, adminResetMatches,
      clearNotifications, adminApproveTransaction, adminCancelTransaction,
    }}>
      {children}
    </AppContext.Provider>
  );
};

export const useApp = () => {
  const context = useContext(AppContext);
  if (!context) throw new Error('useApp must be used within AppProvider');
  return context;
};
