/* @name cardsTableExists */
SELECT EXISTS (
    SELECT FROM information_schema.tables
    WHERE  table_schema = 'public'
    AND    table_name   = 'cards'
);

/* @name insertCard */
INSERT INTO cards
    (token_id, owner, element, power, name, block_height)
VALUES
    (:token_id!, :owner!, :element!, :power!, :name!, :block_height!)
ON CONFLICT (token_id) DO NOTHING;

/* @name updateCardOwner */
UPDATE cards SET owner = :owner! WHERE token_id = :token_id!;

/* @name getCardByTokenId */
SELECT * FROM cards WHERE token_id = :token_id!;

/* @name getCards */
SELECT * FROM cards ORDER BY block_height DESC, token_id DESC;

/* @name getMap */
SELECT m.x, m.y, m.token_id, m.owner, m.placed_at_height,
       c.element, c.power, c.name
FROM map_cells m
JOIN cards c ON c.token_id = m.token_id
ORDER BY m.y, m.x;

/* @name getCell */
SELECT m.x, m.y, m.token_id, m.owner,
       c.element, c.power, c.name
FROM map_cells m
JOIN cards c ON c.token_id = m.token_id
WHERE m.x = :x! AND m.y = :y!;

/* @name getNeighbors */
SELECT m.x, m.y, m.owner,
       c.element, c.power
FROM map_cells m
JOIN cards c ON c.token_id = m.token_id
WHERE (ABS(m.x - :x!) + ABS(m.y - :y!)) = 1;

/* @name isTokenPlaced */
SELECT token_id FROM map_cells WHERE token_id = :token_id!;

/* @name placeCard */
INSERT INTO map_cells
    (x, y, token_id, owner, placed_at_height)
VALUES
    (:x!, :y!, :token_id!, :owner!, :placed_at_height!)
ON CONFLICT (x, y)
DO UPDATE SET
    token_id = EXCLUDED.token_id,
    owner = EXCLUDED.owner,
    placed_at_height = EXCLUDED.placed_at_height;

/* @name decrementCardPower */
UPDATE cards
SET power = GREATEST(:min_power!, power - :amount!)
WHERE token_id = :token_id!;

/* @name insertBattle */
INSERT INTO battle_log
    (x, y, attacker, defender, attacker_token, defender_token,
     attacker_total, defender_total, attacker_won, block_height)
VALUES
    (:x!, :y!, :attacker!, :defender!, :attacker_token!, :defender_token!,
     :attacker_total!, :defender_total!, :attacker_won!, :block_height!);

/* @name getBattles */
SELECT * FROM battle_log ORDER BY id DESC LIMIT 20;

/* @name getLeaderboard */
SELECT owner, COUNT(*)::int AS cells
FROM map_cells
GROUP BY owner
ORDER BY cells DESC;

/* @name getSeason */
SELECT * FROM season WHERE id = 1;

/* @name updateSeason */
UPDATE season
SET element = :element!, counter_value = :counter_value!, block_height = :block_height!
WHERE id = 1;
