-- Rate Limit Alert Configuration
-- Stores alert thresholds and tracks alert state

-- Alert configuration table
CREATE TABLE IF NOT EXISTS public.rate_limit_alert_config (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  metric_type TEXT NOT NULL CHECK (metric_type IN ('block_rate', 'total_requests', 'unique_ips', 'function_specific')),
  threshold_value NUMERIC NOT NULL,
  time_window_ms INTEGER NOT NULL DEFAULT 60000,
  function_name TEXT, -- nullable, only for function_specific alerts
  enabled BOOLEAN NOT NULL DEFAULT true,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  created_by UUID REFERENCES auth.users(id),
  CONSTRAINT unique_alert_config UNIQUE (metric_type, function_name)
);

-- Alert history table (tracks when alerts were triggered)
CREATE TABLE IF NOT EXISTS public.rate_limit_alerts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  config_id UUID REFERENCES public.rate_limit_alert_config(id) ON DELETE CASCADE,
  metric_type TEXT NOT NULL,
  metric_value NUMERIC NOT NULL,
  threshold_value NUMERIC NOT NULL,
  time_window_ms INTEGER NOT NULL,
  function_name TEXT,
  alert_message TEXT NOT NULL,
  resolved_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Enable RLS
ALTER TABLE public.rate_limit_alert_config ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.rate_limit_alerts ENABLE ROW LEVEL SECURITY;

-- RLS Policies for alert config (admin/moderator only)
CREATE POLICY "Moderators can view alert configs"
ON public.rate_limit_alert_config
FOR SELECT
TO authenticated
USING (
  EXISTS (
    SELECT 1 FROM public.user_roles
    WHERE user_id = auth.uid()
    AND role IN ('admin', 'moderator', 'superuser')
  )
);

CREATE POLICY "Admins can manage alert configs"
ON public.rate_limit_alert_config
FOR ALL
TO authenticated
USING (
  EXISTS (
    SELECT 1 FROM public.user_roles
    WHERE user_id = auth.uid()
    AND role IN ('admin', 'superuser')
  )
)
WITH CHECK (
  EXISTS (
    SELECT 1 FROM public.user_roles
    WHERE user_id = auth.uid()
    AND role IN ('admin', 'superuser')
  )
);

-- RLS Policies for alert history (moderators can view)
CREATE POLICY "Moderators can view alert history"
ON public.rate_limit_alerts
FOR SELECT
TO authenticated
USING (
  EXISTS (
    SELECT 1 FROM public.user_roles
    WHERE user_id = auth.uid()
    AND role IN ('admin', 'moderator', 'superuser')
  )
);

CREATE POLICY "System can insert alerts"
ON public.rate_limit_alerts
FOR INSERT
TO authenticated
WITH CHECK (true);

-- Indexes for performance
CREATE INDEX IF NOT EXISTS idx_rate_limit_alert_config_enabled ON public.rate_limit_alert_config(enabled);
CREATE INDEX IF NOT EXISTS idx_rate_limit_alert_config_metric_type ON public.rate_limit_alert_config(metric_type);
CREATE INDEX IF NOT EXISTS idx_rate_limit_alerts_created_at ON public.rate_limit_alerts(created_at DESC);
CREATE INDEX IF NOT EXISTS idx_rate_limit_alerts_config_id ON public.rate_limit_alerts(config_id);
CREATE INDEX IF NOT EXISTS idx_rate_limit_alerts_resolved ON public.rate_limit_alerts(resolved_at) WHERE resolved_at IS NULL;

-- Function to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_rate_limit_alert_config_updated_at()
RETURNS TRIGGER AS $$
BEGIN
  NEW.updated_at = now();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Trigger for updated_at
CREATE TRIGGER update_rate_limit_alert_config_updated_at
BEFORE UPDATE ON public.rate_limit_alert_config
FOR EACH ROW
EXECUTE FUNCTION update_rate_limit_alert_config_updated_at();

-- Insert default alert configurations
INSERT INTO public.rate_limit_alert_config (metric_type, threshold_value, time_window_ms, enabled)
VALUES 
  ('block_rate', 0.5, 300000, true), -- Alert if block rate > 50% in 5 minutes
  ('total_requests', 1000, 60000, true), -- Alert if total requests > 1000/minute
  ('unique_ips', 100, 300000, false) -- Alert if unique IPs > 100 in 5 minutes (disabled by default)
ON CONFLICT (metric_type, function_name) DO NOTHING;

-- Grant necessary permissions
GRANT SELECT, INSERT ON public.rate_limit_alerts TO authenticated;
GRANT SELECT ON public.rate_limit_alert_config TO authenticated;