/* ============================================================
   Solitaire — Klondike for ATHARV.OS
   Adapted from uploads/Solitaire.jsx (logic untouched; only the
   import/export shell stripped for Babel-standalone globals).
============================================================ */

// ===== Constants =====
const SOL_SUITS = ['♠', '♥', '♦', '♣'];
const SOL_RANKS = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
const SOL_RED = new Set(['♥', '♦']);

// ===== Helpers =====
const solRankIdx = (r) => SOL_RANKS.indexOf(r);
const solIsRed = (card) => SOL_RED.has(card.suit);
const solIsOppositeColor = (a, b) => solIsRed(a) !== solIsRed(b);

function solBuildDeck() {
  const deck = [];
  let id = 0;
  for (const suit of SOL_SUITS) {
    for (const rank of SOL_RANKS) {
      deck.push({ id: id++, suit, rank, faceUp: false });
    }
  }
  return deck;
}

function solShuffle(deck) {
  const a = [...deck];
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

function solDealNewGame() {
  const deck = solShuffle(solBuildDeck());
  const tableau = [[], [], [], [], [], [], []];
  let cursor = 0;
  for (let col = 0; col < 7; col++) {
    for (let row = 0; row <= col; row++) {
      const card = { ...deck[cursor++], faceUp: row === col };
      tableau[col].push(card);
    }
  }
  const stock = deck.slice(cursor).map((c) => ({ ...c, faceUp: false }));
  return {
    tableau,
    stock,
    waste: [],
    foundations: [[], [], [], []],
  };
}

function solCanPlaceOnTableau(card, target) {
  if (!target) return card.rank === 'K';
  if (!target.faceUp) return false;
  return solIsOppositeColor(card, target) && solRankIdx(card.rank) === solRankIdx(target.rank) - 1;
}

function solCanPlaceOnFoundation(card, foundation) {
  if (foundation.length === 0) return card.rank === 'A';
  const top = foundation[foundation.length - 1];
  return card.suit === top.suit && solRankIdx(card.rank) === solRankIdx(top.rank) + 1;
}

// ===== Card visual =====
function SolCardView({ card, selected, onClick, onDoubleClick, style }) {
  const baseStyle = {
    width: 64,
    height: 92,
    border: '1px solid #000',
    borderRadius: 4,
    background: card.faceUp ? '#fff' : '#1c4a96',
    color: card.faceUp ? (solIsRed(card) ? '#c50000' : '#000') : '#fff',
    fontFamily: '"MS Sans Serif", Tahoma, sans-serif',
    fontWeight: 700,
    fontSize: 12,
    boxShadow: selected ? '0 0 0 2px #FFD700, 0 0 0 3px #000' : '1px 1px 0 rgba(0,0,0,0.4)',
    cursor: 'pointer',
    userSelect: 'none',
    position: 'relative',
    overflow: 'hidden',
    ...style,
  };

  if (!card.faceUp) {
    return (
      <div style={baseStyle} onClick={onClick}>
        <div
          style={{
            position: 'absolute',
            inset: 4,
            background:
              'repeating-linear-gradient(45deg, #2a5fb8 0 4px, #1c4a96 4px 8px), repeating-linear-gradient(-45deg, transparent 0 4px, rgba(255,255,255,0.15) 4px 8px)',
            border: '1px solid #fff',
            borderRadius: 2,
          }}
        />
      </div>
    );
  }

  return (
    <div style={baseStyle} onClick={onClick} onDoubleClick={onDoubleClick}>
      <div style={{ position: 'absolute', top: 4, left: 6, lineHeight: 1.0 }}>
        <div>{card.rank}</div>
        <div style={{ fontSize: 14 }}>{card.suit}</div>
      </div>
      <div
        style={{
          position: 'absolute',
          inset: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          fontSize: 28,
        }}
      >
        {card.suit}
      </div>
      <div
        style={{
          position: 'absolute',
          bottom: 4,
          right: 6,
          lineHeight: 1.0,
          transform: 'rotate(180deg)',
        }}
      >
        <div>{card.rank}</div>
        <div style={{ fontSize: 14 }}>{card.suit}</div>
      </div>
    </div>
  );
}

function SolEmptySlot({ onClick, label }) {
  return (
    <div
      onClick={onClick}
      style={{
        width: 64,
        height: 92,
        border: '1px dashed rgba(255,255,255,0.5)',
        borderRadius: 4,
        background: 'rgba(0,0,0,0.08)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        color: 'rgba(255,255,255,0.55)',
        fontSize: 12,
        fontFamily: '"MS Sans Serif", Tahoma, sans-serif',
        cursor: 'pointer',
        userSelect: 'none',
      }}
    >
      {label}
    </div>
  );
}

// ===== Main Component =====
function Solitaire({ onClose, onClick }) {
  const [game, setGame] = React.useState(() => solDealNewGame());
  const [selected, setSelected] = React.useState(null);
  const [moves, setMoves] = React.useState(0);
  const [seconds, setSeconds] = React.useState(0);
  const [won, setWon] = React.useState(false);

  React.useEffect(() => {
    if (won) return;
    const id = setInterval(() => setSeconds((s) => s + 1), 1000);
    return () => clearInterval(id);
  }, [won]);

  React.useEffect(() => {
    const total = game.foundations.reduce((s, f) => s + f.length, 0);
    if (total === 52 && !won) setWon(true);
  }, [game, won]);

  const newGame = React.useCallback(() => {
    setGame(solDealNewGame());
    setSelected(null);
    setMoves(0);
    setSeconds(0);
    setWon(false);
    onClick?.();
  }, [onClick]);

  const drawFromStock = React.useCallback(() => {
    setSelected(null);
    setGame((g) => {
      if (g.stock.length === 0) {
        if (g.waste.length === 0) return g;
        const newStock = [...g.waste].reverse().map((c) => ({ ...c, faceUp: false }));
        return { ...g, stock: newStock, waste: [] };
      }
      const next = [...g.stock];
      const card = next.pop();
      card.faceUp = true;
      return { ...g, stock: next, waste: [...g.waste, card] };
    });
    setMoves((m) => m + 1);
    onClick?.();
  }, [onClick]);

  const getSelectedCards = React.useCallback(() => {
    if (!selected) return null;
    if (selected.source === 'waste') {
      const top = game.waste[game.waste.length - 1];
      return top ? [top] : null;
    }
    if (selected.source === 'foundation') {
      const f = game.foundations[selected.col];
      const top = f[f.length - 1];
      return top ? [top] : null;
    }
    if (selected.source === 'tableau') {
      return game.tableau[selected.col].slice(selected.idx);
    }
    return null;
  }, [selected, game]);

  const clearFromSource = React.useCallback((state, source) => {
    if (source.source === 'waste') {
      return { ...state, waste: state.waste.slice(0, -1) };
    }
    if (source.source === 'foundation') {
      const next = state.foundations.map((f, i) =>
        i === source.col ? f.slice(0, -1) : f
      );
      return { ...state, foundations: next };
    }
    if (source.source === 'tableau') {
      const col = [...state.tableau[source.col]];
      col.splice(source.idx);
      if (col.length > 0 && !col[col.length - 1].faceUp) {
        col[col.length - 1] = { ...col[col.length - 1], faceUp: true };
      }
      const newTableau = state.tableau.map((c, i) => (i === source.col ? col : c));
      return { ...state, tableau: newTableau };
    }
    return state;
  }, []);

  const moveTo = React.useCallback(
    (target) => {
      const cards = getSelectedCards();
      if (!cards) return;
      if (target.source === 'tableau') {
        const col = game.tableau[target.col];
        const topTarget = col[col.length - 1];
        const head = cards[0];
        if (!solCanPlaceOnTableau(head, topTarget) && !(col.length === 0 && head.rank === 'K')) {
          setSelected(null);
          return;
        }
        setGame((g) => {
          const cleared = clearFromSource(g, selected);
          const newTab = cleared.tableau.map((c, i) =>
            i === target.col ? [...c, ...cards] : c
          );
          return { ...cleared, tableau: newTab };
        });
        setMoves((m) => m + 1);
        setSelected(null);
        onClick?.();
        return;
      }
      if (target.source === 'foundation') {
        if (cards.length !== 1) {
          setSelected(null);
          return;
        }
        const f = game.foundations[target.col];
        if (!solCanPlaceOnFoundation(cards[0], f)) {
          setSelected(null);
          return;
        }
        setGame((g) => {
          const cleared = clearFromSource(g, selected);
          const newFnd = cleared.foundations.map((c, i) =>
            i === target.col ? [...c, cards[0]] : c
          );
          return { ...cleared, foundations: newFnd };
        });
        setMoves((m) => m + 1);
        setSelected(null);
        onClick?.();
        return;
      }
    },
    [game, selected, getSelectedCards, clearFromSource, onClick]
  );

  const onClickTableauCard = (col, idx) => {
    const card = game.tableau[col][idx];
    if (!card.faceUp) return;
    if (selected) {
      moveTo({ source: 'tableau', col });
    } else {
      setSelected({ source: 'tableau', col, idx });
    }
  };

  const onClickWaste = () => {
    if (game.waste.length === 0) return;
    if (selected && selected.source === 'waste') {
      setSelected(null);
      return;
    }
    if (selected) {
      setSelected({ source: 'waste' });
      return;
    }
    setSelected({ source: 'waste' });
  };

  const onClickFoundation = (col) => {
    if (selected) {
      moveTo({ source: 'foundation', col });
    } else if (game.foundations[col].length > 0) {
      setSelected({ source: 'foundation', col });
    }
  };

  const onClickEmptyTableau = (col) => {
    if (selected) moveTo({ source: 'tableau', col });
  };

  const onDoubleClickCard = (source) => {
    const cards =
      source.source === 'tableau'
        ? [game.tableau[source.col][game.tableau[source.col].length - 1]]
        : source.source === 'waste'
        ? [game.waste[game.waste.length - 1]]
        : null;
    if (!cards || !cards[0] || !cards[0].faceUp) return;
    const card = cards[0];
    for (let i = 0; i < 4; i++) {
      if (solCanPlaceOnFoundation(card, game.foundations[i])) {
        setSelected(source);
        setTimeout(() => moveTo({ source: 'foundation', col: i }), 0);
        return;
      }
    }
  };

  const fmtTime = (s) => `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;

  const isSelected = (src) =>
    selected &&
    selected.source === src.source &&
    selected.col === src.col &&
    selected.idx === src.idx;

  const menuBtnStyle = {
    background: 'transparent',
    border: '1px solid transparent',
    padding: '2px 6px',
    fontFamily: 'inherit',
    fontSize: 11,
    cursor: 'pointer',
  };
  const win95BtnStyle = {
    background: '#C0C0C0',
    border: '2px solid',
    borderColor: '#FFFFFF #404040 #404040 #FFFFFF',
    padding: '4px 14px',
    fontFamily: '"MS Sans Serif", Tahoma, sans-serif',
    fontSize: 11,
    cursor: 'pointer',
  };
  const winDialogStyle = {
    background: '#C0C0C0',
    border: '2px solid',
    borderColor: '#FFFFFF #404040 #404040 #FFFFFF',
    padding: 16,
    fontFamily: '"MS Sans Serif", Tahoma, sans-serif',
    color: '#000',
    textAlign: 'center',
    minWidth: 200,
  };

  return (
    <div
      style={{
        background: '#008000',
        padding: 16,
        fontFamily: '"MS Sans Serif", Tahoma, sans-serif',
        userSelect: 'none',
        minHeight: '100%',
        position: 'relative',
      }}
    >
      <div
        style={{
          background: '#C0C0C0',
          padding: '2px 4px',
          margin: -16,
          marginBottom: 12,
          display: 'flex',
          gap: 2,
          fontSize: 11,
          borderBottom: '1px solid #808080',
        }}
      >
        <button onClick={newGame} style={menuBtnStyle}>
          <span style={{ textDecoration: 'underline' }}>G</span>ame
        </button>
        <button style={menuBtnStyle}>
          <span style={{ textDecoration: 'underline' }}>H</span>elp
        </button>
        <div style={{ flex: 1 }} />
        <div style={{ padding: '2px 8px', color: '#000' }}>
          Moves: {moves} · Time: {fmtTime(seconds)}
        </div>
      </div>

      <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
        <div onClick={drawFromStock}>
          {game.stock.length > 0 ? (
            <SolCardView card={{ ...game.stock[game.stock.length - 1], faceUp: false }} />
          ) : (
            <SolEmptySlot label="↻" />
          )}
        </div>

        {game.waste.length > 0 ? (
          <SolCardView
            card={game.waste[game.waste.length - 1]}
            selected={isSelected({ source: 'waste' })}
            onClick={onClickWaste}
            onDoubleClick={() => onDoubleClickCard({ source: 'waste' })}
          />
        ) : (
          <SolEmptySlot label="" />
        )}

        <div style={{ flex: 1 }} />

        {game.foundations.map((f, i) =>
          f.length > 0 ? (
            <SolCardView
              key={i}
              card={f[f.length - 1]}
              selected={isSelected({ source: 'foundation', col: i })}
              onClick={() => onClickFoundation(i)}
            />
          ) : (
            <SolEmptySlot key={i} label={SOL_SUITS[i]} onClick={() => onClickFoundation(i)} />
          )
        )}
      </div>

      <div style={{ display: 'flex', gap: 12 }}>
        {game.tableau.map((col, ci) => (
          <div key={ci} style={{ position: 'relative', width: 64, minHeight: 92 }}>
            {col.length === 0 ? (
              <SolEmptySlot onClick={() => onClickEmptyTableau(ci)} />
            ) : (
              col.map((card, idx) => (
                <div
                  key={card.id}
                  style={{
                    position: 'absolute',
                    top: idx * 22,
                    left: 0,
                    zIndex: idx,
                  }}
                  onDoubleClick={
                    idx === col.length - 1
                      ? () => onDoubleClickCard({ source: 'tableau', col: ci })
                      : undefined
                  }
                >
                  <SolCardView
                    card={card}
                    selected={isSelected({ source: 'tableau', col: ci, idx })}
                    onClick={() => onClickTableauCard(ci, idx)}
                  />
                </div>
              ))
            )}
          </div>
        ))}
      </div>

      {won && (
        <div
          style={{
            position: 'absolute',
            inset: 0,
            background: 'rgba(0,0,0,0.55)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            zIndex: 100,
          }}
        >
          <div style={winDialogStyle}>
            <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 8 }}>You Won!</div>
            <div style={{ fontSize: 11, marginBottom: 12 }}>
              Moves: {moves}<br/>Time: {fmtTime(seconds)}
            </div>
            <button onClick={newGame} style={win95BtnStyle}>New Game</button>
          </div>
        </div>
      )}
    </div>
  );
}

/* ============================================================
   Lightweight global SFX — minimal Web Audio click tick.
   Respects window.__atharvMuted (set by tray volume control).
============================================================ */
window.sfx = window.sfx || {
  click: () => {
    try {
      if (window.__atharvMuted) return;
      const Ctx = window.AudioContext || window.webkitAudioContext;
      if (!Ctx) return;
      window.__sfxCtx = window.__sfxCtx || new Ctx();
      const ctx = window.__sfxCtx;
      if (ctx.state === 'suspended') ctx.resume();
      const o = ctx.createOscillator();
      const g = ctx.createGain();
      o.type = 'square';
      o.frequency.setValueAtTime(1800, ctx.currentTime);
      g.gain.setValueAtTime(0.06, ctx.currentTime);
      g.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + 0.04);
      o.connect(g).connect(ctx.destination);
      o.start();
      o.stop(ctx.currentTime + 0.05);
    } catch (e) {}
  },
};

Object.assign(window, { Solitaire });
