-- Reshape attribute training to AT MOST ONE effect per instance, replaceable.
--
-- WHY THIS SUPERSEDES 0029'S SHAPE. 0029 keyed on (owned_card_id,
-- attribute_index) and recorded that same-slot behaviour was UNKNOWN, enforcing
-- the unknown as a refusal. That was the honest shape while the semantics were
-- unrecovered. They are now recovered, and BOTH halves of 0029's shape are
-- wrong:
--
--   * "You can only boost one attribute or all six. You can not do it with 2, 3,
--     4 or 5 attributes." -- so two effects must never coexist on one instance,
--     which the old composite key permitted (and which staging demonstrated by
--     holding a slot-4 and a slot-1 effect at once).
--   * "When you apply a new training card to a player, he loses the improved
--     attributes of previous training cards. It does not accumulate, it
--     replaces." -- so a second apply REPLACES, it does not refuse.
--
-- Both quotes are from the contemporaneous FIFA 17-specific training guide
-- (fifauteam, published 2016-09-08), corroborated by the shipped table: each
-- family has exactly 21 rows = 7 card types x 3 levels, and the 7th type in each
-- family (subtypes 57 and 67) is the only one flagged `weightrare = 2` with
-- amounts 3/6/10, matching the documented RARE "ALL" card at +3/+6/+10.
-- DOCUMENTED, corroborated TABLE_PROVEN. It is NOT LIVE_PROVEN against EA.
--
-- 0029 is left intact rather than rewritten: it is already applied to the
-- supervised staging environment, so migration history matters there.
--
-- NEW SHAPE. One row per instance, so "one attribute or all six" is a
-- representable invariant instead of a convention:
--   attribute_index INTEGER NULL -- a slot in Core's six-attribute model, or
--                                   NULL meaning ALL SIX slots (the rare card).
-- The PRIMARY KEY on owned_card_id alone is what makes a second application a
-- REPLACE (delete-then-insert inside the one apply transaction) rather than an
-- accumulation.
--
-- The 1..=15 amount bound is NOT tightened here: 15 is the single-attribute
-- ceiling while the all-six card authors at most 10, and which ceiling applies
-- depends on the card family -- a per-game rule that belongs at apply time where
-- the game's table is in scope, not in the schema.
--
-- DATA CARRIED FORWARD: where an instance somehow holds several effects (only
-- reachable on staging under 0029's shape), the MOST RECENT survives, which is
-- exactly the "replaces" rule applied retroactively.

CREATE TABLE owned_card_training_new (
    owned_card_id   TEXT    NOT NULL PRIMARY KEY REFERENCES owned_cards(id) ON DELETE CASCADE,
    attribute_index INTEGER          CHECK (attribute_index IS NULL OR attribute_index BETWEEN 0 AND 5),
    amount          INTEGER NOT NULL CHECK (amount >= 1 AND amount <= 99),
    source_card_id  TEXT    NOT NULL,
    applied_at      TEXT    NOT NULL
);

INSERT INTO owned_card_training_new
    (owned_card_id, attribute_index, amount, source_card_id, applied_at)
SELECT t.owned_card_id, t.attribute_index, t.amount, t.source_card_id, t.applied_at
  FROM owned_card_training t
  JOIN (
        SELECT owned_card_id, MAX(applied_at) AS newest
          FROM owned_card_training
         GROUP BY owned_card_id
       ) pick
    ON pick.owned_card_id = t.owned_card_id
   AND pick.newest        = t.applied_at
 GROUP BY t.owned_card_id;

DROP TABLE owned_card_training;
ALTER TABLE owned_card_training_new RENAME TO owned_card_training;
