// firebase-sync.jsx — Firebase logic and Room Splash Screen
const { useState, useEffect, useCallback } = React;

// 1. Firebase Configuration
const firebaseConfig = {
  apiKey: "AIzaSyDZnlTBp4tUdwKv9uEBQOaiP0Q_FKyCTeE",
  authDomain: "lol-clash-builder.firebaseapp.com",
  databaseURL: "https://lol-clash-builder-default-rtdb.firebaseio.com",
  projectId: "lol-clash-builder",
  storageBucket: "lol-clash-builder.firebasestorage.app",
  messagingSenderId: "1002811514175",
  appId: "1:1002811514175:web:55915fe4da38dd7c28478a",
  measurementId: "G-TZH420G3L7"
};

// Initialize Firebase only once
let db = null;
try {
  if (typeof firebase !== 'undefined') {
    if (!firebase.apps.length) {
      firebase.initializeApp(firebaseConfig);
    }
    db = firebase.database();
    window.db = db;
  } else {
    console.warn("Firebase SDK not found.");
  }
} catch (e) {
  console.error("Firebase init failed:", e);
}

const firebaseToArray = (val) => {
  if (!val) return [];
  if (Array.isArray(val)) return val.filter(Boolean);
  if (typeof val === 'object') return Object.values(val).filter(Boolean);
  return [];
};

const sanitizeSavedCompsHelper = (comps) => {
  return firebaseToArray(comps).map(c => {
    if (!c) return null;
    return {
      ...c,
      notes: firebaseToArray(c.notes)
    };
  }).filter(Boolean);
};

function useFirebaseSync(roomCode, initialState) {
  const initialStateRef = React.useRef(initialState);
  useEffect(() => {
    initialStateRef.current = initialState;
  }, [initialState]);

  const roomCodeRef = React.useRef(roomCode);
  const activeListenerRef = React.useRef(null);
  const [isSynced, setIsSynced] = useState(false);

  // Synchronously detach old listener and update roomCodeRef on room switch
  if (roomCodeRef.current !== roomCode) {
    if (activeListenerRef.current) {
      try {
        activeListenerRef.current.ref.off('value', activeListenerRef.current.listener);
      } catch (e) {}
      activeListenerRef.current = null;
    }
    roomCodeRef.current = roomCode;
  }

  const [state, setState] = useState(() => {
    try {
      const saved = localStorage.getItem(`cozydraft-room-${roomCode}`);
      if (saved) {
        const parsed = JSON.parse(saved);
        const parsedPlayers = Array.isArray(parsed?.players) && parsed.players.length >= 5 
          ? parsed.players.map(p => ({
              ...p,
              pool: firebaseToArray(p?.pool) || [],
              subRoles: firebaseToArray(p?.subRoles) || (p.isSub ? ['TOP'] : undefined),
            }))
          : initialState.players;
        return {
          ...initialState,
          ...parsed,
          lobbyCode: roomCode,
          players: parsedPlayers,
          savedComps: sanitizeSavedCompsHelper(parsed?.savedComps || initialState.savedComps),
          activeCompNotes: firebaseToArray(parsed?.activeCompNotes || initialState.activeCompNotes),
        };
      }
    } catch {}
    return { ...initialState, lobbyCode: roomCode };
  });

  useEffect(() => {
    initialStateRef.current = initialState;
  }, [initialState]);

  // Listen to Firebase
  useEffect(() => {
    if (!roomCode) return;
    setIsSynced(false);
    
    // Detach any active listener before setting up a new subscription
    if (activeListenerRef.current) {
      try {
        activeListenerRef.current.ref.off('value', activeListenerRef.current.listener);
      } catch (e) {}
      activeListenerRef.current = null;
    }
    
    // Load local storage / initial state for the new room code immediately on change
    try {
      const saved = localStorage.getItem(`cozydraft-room-${roomCode}`);
      if (saved) {
        const parsed = JSON.parse(saved);
        const parsedPlayers = Array.isArray(parsed?.players) && parsed.players.length >= 5 
          ? parsed.players.map(p => ({
              ...p,
              pool: firebaseToArray(p?.pool) || [],
              subRoles: firebaseToArray(p?.subRoles) || (p.isSub ? ['TOP'] : undefined),
            }))
          : initialStateRef.current.players;
        setState(s => {
          const next = {
            ...initialStateRef.current,
            ...parsed,
            lobbyCode: roomCode,
            // Preserve local-only fields
            myUserId: s ? s.myUserId : (parsed.myUserId !== undefined ? parsed.myUserId : initialStateRef.current.myUserId),
            onboarded: s ? s.onboarded : (parsed.onboarded !== undefined ? parsed.onboarded : initialStateRef.current.onboarded),
            activePlayerId: s ? s.activePlayerId : (parsed.activePlayerId !== undefined ? parsed.activePlayerId : initialStateRef.current.activePlayerId),
            savedComps: sanitizeSavedCompsHelper(parsed?.savedComps || initialStateRef.current.savedComps),
            activeCompNotes: firebaseToArray(parsed?.activeCompNotes || initialStateRef.current.activeCompNotes),
          };
          if (s && JSON.stringify(s) === JSON.stringify(next)) return s;
          return next;
        });
      } else {
        setState(s => {
          const next = {
            ...initialStateRef.current,
            lobbyCode: roomCode,
            // Preserve local-only fields
            myUserId: s ? s.myUserId : initialStateRef.current.myUserId,
            onboarded: s ? s.onboarded : initialStateRef.current.onboarded,
            activePlayerId: s ? s.activePlayerId : initialStateRef.current.activePlayerId,
          };
          if (s && JSON.stringify(s) === JSON.stringify(next)) return s;
          return next;
        });
      }
    } catch {
      setState(s => {
        const next = {
          ...initialStateRef.current,
          lobbyCode: roomCode,
          myUserId: s ? s.myUserId : initialStateRef.current.myUserId,
          onboarded: s ? s.onboarded : initialStateRef.current.onboarded,
          activePlayerId: s ? s.activePlayerId : initialStateRef.current.activePlayerId,
        };
        if (s && JSON.stringify(s) === JSON.stringify(next)) return s;
        return next;
      });
    }

    if (!db) {
      setIsSynced(true);
      return;
    }

    let roomRef;
    let listener;
    try {
      roomRef = db.ref(`rooms/${roomCode}/state`);
      listener = roomRef.on('value', (snapshot) => {
        const data = snapshot.val();
        if (data) {
          // Merge with initial state to ensure no missing fields
          setState(s => {
            const rawPlayers = data?.players;
            const safePlayers = firebaseToArray(rawPlayers).length >= 5
              ? firebaseToArray(rawPlayers)
              : (Array.isArray(s?.players) && s.players.length >= 5 ? s.players : initialStateRef.current.players);

            const mergedPlayers = safePlayers.map(p => ({
              ...p,
              pool: firebaseToArray(p?.pool) || [],
              subRoles: firebaseToArray(p?.subRoles) || (p.isSub ? ['TOP'] : undefined),
            }));

            const safeState = {
              ...initialStateRef.current,
              ...data,
              lobbyCode: roomCode,
              roomNotFound: false,
              // Preserve local-only fields
              myUserId: s ? s.myUserId : (data.myUserId !== undefined ? data.myUserId : initialStateRef.current.myUserId),
              onboarded: s ? s.onboarded : (data.onboarded !== undefined ? data.onboarded : initialStateRef.current.onboarded),
              activePlayerId: s ? s.activePlayerId : (data.activePlayerId !== undefined ? data.activePlayerId : initialStateRef.current.activePlayerId),
              players: mergedPlayers,
              savedComps: data?.savedComps !== undefined ? sanitizeSavedCompsHelper(data.savedComps) : (s?.savedComps !== undefined ? sanitizeSavedCompsHelper(s.savedComps) : sanitizeSavedCompsHelper(initialStateRef.current.savedComps)),
              activeCompNotes: data?.activeCompNotes !== undefined ? firebaseToArray(data.activeCompNotes) : (s?.activeCompNotes !== undefined ? firebaseToArray(s.activeCompNotes) : []),
            };
            
            if (s && JSON.stringify(s) === JSON.stringify(safeState)) {
              return s;
            }
            
            try { localStorage.setItem(`cozydraft-room-${roomCode}`, JSON.stringify(safeState)); } catch {}
            return safeState;
          });
        } else {
          // Check if this room was just created by this client
          if (window.recentlyCreatedLobbies && window.recentlyCreatedLobbies.has(roomCode)) {
            // Suppress missing-room redirect during initial propagation of freshly created rooms
            setIsSynced(true);
            return;
          }

          // Room node does not exist in Firebase (deleted or invalid)
          try {
            localStorage.removeItem(`cozydraft-room-${roomCode}`);
            localStorage.removeItem('cozydraft-lobbycode');
          } catch (e) {}

          setState(s => ({
            ...initialStateRef.current,
            lobbyCode: null,
            roomNotFound: true,
            myUserId: s ? s.myUserId : initialStateRef.current.myUserId,
            onboarded: true,
            activePlayerId: s ? s.activePlayerId : initialStateRef.current.activePlayerId,
          }));
        }
        setIsSynced(true);
      }, (error) => {
        console.error("Firebase listen error:", error);
        setIsSynced(true);
      });
      activeListenerRef.current = { ref: roomRef, listener };
    } catch (err) {
      console.error("Firebase setup error:", err);
      setIsSynced(true);
    }

    return () => {
      try {
        if (roomRef && listener) roomRef.off('value', listener);
      } catch {}
      if (activeListenerRef.current?.listener === listener) {
        activeListenerRef.current = null;
      }
    };
  }, [roomCode]);

  // Push changes to Firebase (we return a custom setter)
  const setSyncedState = useCallback((updater) => {
    setState((prevState) => {
      const newState = typeof updater === 'function' ? updater(prevState) : updater;
      
      const currentRoom = roomCodeRef.current;
      // Update offline fallback
      try { localStorage.setItem(`cozydraft-room-${currentRoom}`, JSON.stringify(newState)); } catch {}
      
      if (db && currentRoom) {
        if (prevState) {
          const updates = {};
          let hasChanges = false;
          
          for (const key in newState) {
            // Skip local-only keys
            if (key === 'myUserId' || key === 'onboarded' || key === 'activePlayerId' || key === 'toast' || key === 'currentTab' || key === 'lobbyCode') {
              continue;
            }
            
            if (newState[key] !== prevState[key]) {
              if (key === 'players' && Array.isArray(newState.players) && Array.isArray(prevState.players)) {
                const maxLen = Math.max(newState.players.length, prevState.players.length);
                for (let idx = 0; idx < maxLen; idx++) {
                  const p = newState.players[idx];
                  const prevP = prevState.players[idx];

                  if (!p && prevP) {
                    updates[`players/${idx}`] = null;
                    hasChanges = true;
                  } else if (p && !prevP) {
                    updates[`players/${idx}`] = p;
                    hasChanges = true;
                  } else if (p && prevP && p !== prevP) {
                    if (p.name !== prevP.name) {
                      updates[`players/${idx}/name`] = p.name;
                      hasChanges = true;
                    }
                    if (p.identityColor !== prevP.identityColor) {
                      updates[`players/${idx}/identityColor`] = p.identityColor;
                      hasChanges = true;
                    }
                    if (p.claimed !== prevP.claimed) {
                      updates[`players/${idx}/claimed`] = p.claimed;
                      hasChanges = true;
                    }
                    if (p.online !== prevP.online) {
                      updates[`players/${idx}/online`] = p.online;
                      hasChanges = true;
                    }
                    if (p.position !== prevP.position) {
                      updates[`players/${idx}/position`] = p.position;
                      hasChanges = true;
                    }
                    if (p.available !== prevP.available) {
                      updates[`players/${idx}/available`] = p.available === undefined ? null : p.available;
                      hasChanges = true;
                    }
                    if (p.subRoles !== prevP.subRoles) {
                      updates[`players/${idx}/subRoles`] = p.subRoles === undefined ? null : p.subRoles;
                      hasChanges = true;
                    }
                    if (p.isSub !== prevP.isSub) {
                      updates[`players/${idx}/isSub`] = p.isSub === undefined ? null : p.isSub;
                      hasChanges = true;
                    }
                    if (p.pool !== prevP.pool) {
                      const newPoolEmpty = !p.pool || (Array.isArray(p.pool) && p.pool.length === 0);
                      const prevPoolPopulated = prevP.pool && Array.isArray(prevP.pool) && prevP.pool.length > 0;
                      if (newPoolEmpty && prevPoolPopulated && !p._explicitPoolAction) {
                        console.warn(`[FirebaseSync] Guard blocked overwriting populated pool for player index ${idx} (${prevP.name}) with empty pool.`);
                      } else {
                        updates[`players/${idx}/pool`] = p.pool || [];
                        hasChanges = true;
                      }
                    }
                    if (p.focusPicksSetAt !== prevP.focusPicksSetAt) {
                      updates[`players/${idx}/focusPicksSetAt`] = p.focusPicksSetAt === undefined ? null : p.focusPicksSetAt;
                      hasChanges = true;
                    }
                    if (p.ownerId !== prevP.ownerId) {
                      updates[`players/${idx}/ownerId`] = p.ownerId === undefined ? null : p.ownerId;
                      hasChanges = true;
                    }
                  }
                }
              } else if (key === 'activeComp' && newState.activeComp && prevState.activeComp) {
                for (const pos in newState.activeComp) {
                  if (newState.activeComp[pos] !== prevState.activeComp[pos]) {
                    updates[`activeComp/${pos}`] = newState.activeComp[pos] === undefined ? null : newState.activeComp[pos];
                    hasChanges = true;
                  }
                }
              } else if (key === 'clashReadiness' && newState.clashReadiness && prevState.clashReadiness) {
                for (const pId in newState.clashReadiness) {
                  if (newState.clashReadiness[pId] !== prevState.clashReadiness[pId]) {
                    updates[`clashReadiness/${pId}`] = newState.clashReadiness[pId] === undefined ? null : newState.clashReadiness[pId];
                    hasChanges = true;
                  }
                }
              } else {
                updates[key] = newState[key] === undefined ? null : newState[key];
                hasChanges = true;
              }
            }
          }
          
          if (hasChanges) {
            db.ref(`rooms/${currentRoom}/state`).update(updates).catch(err => {
              console.error("Firebase update failed:", err);
            });
          }
        } else {
          // Initial write when prevState is not yet populated
          const syncState = {};
          for (const key in newState) {
            if (key !== 'myUserId' && key !== 'onboarded' && key !== 'activePlayerId' && key !== 'toast' && key !== 'currentTab' && key !== 'lobbyCode') {
              syncState[key] = newState[key];
            }
          }
          db.ref(`rooms/${currentRoom}/state`).set(syncState).catch(err => {
            console.error("Firebase initial set failed:", err);
          });
        }
      }
      
      return newState;
    });
  }, []);

  return [state, setSyncedState, isSynced];
}

// 3. Splash Screen Component
function RoomSplashScreen({ onJoin }) {
  const [code, setCode] = useState('');
  const [error, setError] = useState('');

  const handleJoin = (e) => {
    e?.preventDefault();
    if (code.length !== 4 || isNaN(Number(code))) {
      setError('Please enter a valid 4-digit code.');
      return;
    }
    onJoin(code);
  };

  const handleCreate = () => {
    const newCode = Math.floor(1000 + Math.random() * 9000).toString();
    onJoin(newCode);
  };

  return (
    <div style={{
      minHeight: '100vh',
      background: '#FFF5E6',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      padding: 20
    }}>
      <div className="cozy-card" style={{
        maxWidth: 400,
        width: '100%',
        padding: '40px 30px',
        textAlign: 'center',
        background: '#FFFAF3'
      }}>
        <div className="float" style={{ fontSize: 64, marginBottom: 16 }}>🌸</div>
        <h1 className="fredoka" style={{ color: '#C4845A', fontSize: 28, marginBottom: 8 }}>
          Cozy Draft
        </h1>
        <p style={{ color: '#4A3728', fontWeight: 600, marginBottom: 32 }}>
          Enter a room code to draft with friends!
        </p>

        <form onSubmit={handleJoin} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div>
            <input
              type="text"
              maxLength={4}
              value={code}
              onChange={(e) => {
                setCode(e.target.value.replace(/\D/g, ''));
                setError('');
              }}
              placeholder="e.g. 1234"
              style={{
                width: '100%',
                padding: '14px',
                fontSize: 24,
                letterSpacing: 8,
                textAlign: 'center',
                fontFamily: 'Fredoka One, cursive',
                color: '#4A3728',
                background: '#FFF5E6',
                border: '2px solid #C4845A40',
                borderRadius: 16,
                outline: 'none',
                transition: 'all 0.2s'
              }}
            />
            {error && <div style={{ color: '#E8A0A0', fontSize: 13, marginTop: 8, fontWeight: 700 }}>{error}</div>}
          </div>

          <button
            type="submit"
            className="cozy-btn"
            style={{
              width: '100%',
              padding: 16,
              background: '#7CBF8E',
              color: 'white',
              border: 'none',
              borderRadius: 16,
              fontSize: 18,
              fontFamily: 'Nunito',
              fontWeight: 800,
              boxShadow: '0 4px 0 #559e6a',
              cursor: 'pointer',
              marginTop: 8
            }}
          >
            Join Room
          </button>
        </form>

        <div style={{ margin: '24px 0', display: 'flex', alignItems: 'center', gap: 12 }}>
          <div style={{ flex: 1, height: 2, background: '#C4845A20', borderRadius: 2 }}></div>
          <span style={{ color: '#C4845A80', fontSize: 14, fontWeight: 700 }}>OR</span>
          <div style={{ flex: 1, height: 2, background: '#C4845A20', borderRadius: 2 }}></div>
        </div>

        <button
          onClick={handleCreate}
          className="cozy-btn"
          style={{
            width: '100%',
            padding: 16,
            background: '#F7DFA0',
            color: '#4A3728',
            border: 'none',
            borderRadius: 16,
            fontSize: 16,
            fontFamily: 'Nunito',
            fontWeight: 800,
            boxShadow: '0 4px 0 #c8ae65',
            cursor: 'pointer'
          }}
        >
          ✨ Create New Room
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { useFirebaseSync, RoomSplashScreen });
