defmodule Aprsme.Repo.Migrations.ReplacePacketCountSequence do
  use Ecto.Migration

  def up do
    execute("DROP TRIGGER IF EXISTS packet_insert_sequence ON packets")
    execute("DROP TRIGGER IF EXISTS packet_delete_sequence ON packets")

    execute("""
    INSERT INTO packet_counters (counter_type, count, inserted_at, updated_at)
    VALUES ('total_packets', 0, NOW(), NOW())
    ON CONFLICT (counter_type) DO NOTHING
    """)

    execute("""
    UPDATE packet_counters
    SET count = (SELECT COUNT(*) FROM packets),
        updated_at = NOW()
    WHERE counter_type = 'total_packets'
    """)

    execute("""
    CREATE OR REPLACE FUNCTION increment_packet_counter()
    RETURNS TRIGGER AS $$
    BEGIN
      UPDATE packet_counters
      SET count = count + 1,
          updated_at = NOW()
      WHERE counter_type = 'total_packets';
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql
    """)

    execute("""
    CREATE OR REPLACE FUNCTION decrement_packet_counter()
    RETURNS TRIGGER AS $$
    BEGIN
      UPDATE packet_counters
      SET count = GREATEST(0, count - 1),
          updated_at = NOW()
      WHERE counter_type = 'total_packets';
      RETURN OLD;
    END;
    $$ LANGUAGE plpgsql
    """)

    execute("""
    CREATE TRIGGER packet_insert_counter
    AFTER INSERT ON packets
    FOR EACH ROW
    EXECUTE FUNCTION increment_packet_counter()
    """)

    execute("""
    CREATE TRIGGER packet_delete_counter
    AFTER DELETE ON packets
    FOR EACH ROW
    EXECUTE FUNCTION decrement_packet_counter()
    """)

    execute("""
    CREATE OR REPLACE FUNCTION get_packet_count()
    RETURNS BIGINT AS $$
    BEGIN
      RETURN COALESCE(
        (SELECT count FROM packet_counters WHERE counter_type = 'total_packets'),
        0
      );
    END;
    $$ LANGUAGE plpgsql STABLE
    """)

    execute("DROP FUNCTION IF EXISTS increment_packet_sequence()")
    execute("DROP FUNCTION IF EXISTS decrement_packet_sequence()")
    execute("DROP SEQUENCE IF EXISTS packet_count_seq")

    execute("""
    COMMENT ON TABLE packet_counters IS
    'Exact retained packet count. Updated atomically by packet DML and partition maintenance.'
    """)
  end

  def down do
    execute("DROP TRIGGER IF EXISTS packet_insert_counter ON packets")
    execute("DROP TRIGGER IF EXISTS packet_delete_counter ON packets")

    execute("""
    CREATE SEQUENCE packet_count_seq
    MINVALUE 0
    START WITH 0
    """)

    execute("""
    SELECT setval(
      'packet_count_seq',
      COALESCE((SELECT count FROM packet_counters WHERE counter_type = 'total_packets'), 0),
      true
    )
    """)

    execute("""
    CREATE OR REPLACE FUNCTION increment_packet_sequence()
    RETURNS TRIGGER AS $$
    BEGIN
      PERFORM nextval('packet_count_seq');
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql
    """)

    execute("""
    CREATE OR REPLACE FUNCTION decrement_packet_sequence()
    RETURNS TRIGGER AS $$
    DECLARE
      current_val BIGINT;
    BEGIN
      SELECT last_value INTO current_val FROM packet_count_seq;
      PERFORM setval('packet_count_seq', GREATEST(0, current_val - 1), true);
      RETURN OLD;
    END;
    $$ LANGUAGE plpgsql
    """)

    execute("""
    CREATE TRIGGER packet_insert_sequence
    AFTER INSERT ON packets
    FOR EACH ROW
    EXECUTE FUNCTION increment_packet_sequence()
    """)

    execute("""
    CREATE TRIGGER packet_delete_sequence
    AFTER DELETE ON packets
    FOR EACH ROW
    EXECUTE FUNCTION decrement_packet_sequence()
    """)

    execute("""
    CREATE OR REPLACE FUNCTION get_packet_count()
    RETURNS BIGINT AS $$
    BEGIN
      RETURN last_value FROM packet_count_seq;
    END;
    $$ LANGUAGE plpgsql STABLE
    """)
  end
end
