-- Meshkee CMS — payment transactions

-- ---------------------------------------------------------------------------
-- enums
-- ---------------------------------------------------------------------------
DO $$ BEGIN
  CREATE TYPE transaction_type AS ENUM (
    'pos',
    'cash',
    'transfer',
    'e_payment_gate'
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

DO $$ BEGIN
  CREATE TYPE transaction_status AS ENUM (
    'pending',
    'completed',
    'failed',
    'refunded'
  );
EXCEPTION
  WHEN duplicate_object THEN NULL;
END $$;

-- ---------------------------------------------------------------------------
-- transactions
-- ---------------------------------------------------------------------------
CREATE TABLE transactions (
  id                   BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
  business_id          BIGINT NOT NULL,
  order_id             BIGINT,
  user_id              BIGINT NOT NULL,
  type                 transaction_type NOT NULL,
  status               transaction_status NOT NULL DEFAULT 'pending',
  amount               NUMERIC(12, 2) NOT NULL,
  pos_type             VARCHAR(100),
  gateway_type         VARCHAR(100),
  transfer_account     VARCHAR(255),
  transfer_ref_number  VARCHAR(100),
  notes                TEXT,
  created_by           BIGINT,
  created_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),
  updated_at           TIMESTAMPTZ NOT NULL DEFAULT NOW(),

  CONSTRAINT transactions_business_id_fkey
    FOREIGN KEY (business_id) REFERENCES businesses (id) ON DELETE CASCADE,
  CONSTRAINT transactions_order_id_fkey
    FOREIGN KEY (order_id) REFERENCES orders (id) ON DELETE SET NULL,
  CONSTRAINT transactions_user_id_fkey
    FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE RESTRICT,
  CONSTRAINT transactions_created_by_fkey
    FOREIGN KEY (created_by) REFERENCES users (id) ON DELETE SET NULL,
  CONSTRAINT transactions_amount_non_negative CHECK (amount >= 0),
  CONSTRAINT transactions_type_fields_check CHECK (
    (type = 'pos'
      AND pos_type IS NOT NULL
      AND gateway_type IS NULL
      AND transfer_account IS NULL
      AND transfer_ref_number IS NULL)
    OR (type = 'cash'
      AND pos_type IS NULL
      AND gateway_type IS NULL
      AND transfer_account IS NULL
      AND transfer_ref_number IS NULL)
    OR (type = 'transfer'
      AND transfer_account IS NOT NULL
      AND transfer_ref_number IS NOT NULL
      AND pos_type IS NULL
      AND gateway_type IS NULL)
    OR (type = 'e_payment_gate'
      AND gateway_type IS NOT NULL
      AND pos_type IS NULL
      AND transfer_account IS NULL
      AND transfer_ref_number IS NULL)
  )
);

CREATE INDEX idx_transactions_business_created
  ON transactions (business_id, created_at DESC);

CREATE INDEX idx_transactions_order_id
  ON transactions (order_id);

CREATE INDEX idx_transactions_business_user
  ON transactions (business_id, user_id, created_at DESC);

CREATE TRIGGER transactions_set_updated_at
  BEFORE UPDATE ON transactions
  FOR EACH ROW
  EXECUTE FUNCTION set_updated_at();

-- ---------------------------------------------------------------------------
-- permissions
-- ---------------------------------------------------------------------------
INSERT INTO permissions (name, slug, group_name, description) VALUES
  ('View transactions', 'transactions.read', 'transactions', 'View payment transactions')
ON CONFLICT (slug) DO NOTHING;

INSERT INTO role_permissions (role_id, permission_id)
SELECT r.id, p.id
FROM roles r
JOIN permissions p ON p.slug = 'transactions.read'
WHERE r.slug IN ('business_owner', 'owner', 'admin')
ON CONFLICT DO NOTHING;

INSERT INTO role_permissions (role_id, permission_id)
SELECT r.id, p.id
FROM roles r
JOIN permissions p ON p.slug = 'transactions.read'
WHERE r.slug = 'editor'
ON CONFLICT DO NOTHING;
