-- Add scanner lock functionality to events table
-- This migration adds support for locking scanner devices to scan-only mode

-- Add scanner lock fields to events table
ALTER TABLE events ADD COLUMN scanner_lock_enabled BOOLEAN DEFAULT FALSE;
ALTER TABLE events ADD COLUMN scanner_pin_hash TEXT;
ALTER TABLE events ADD COLUMN scanner_lock_created_at TIMESTAMP WITH TIME ZONE;
ALTER TABLE events ADD COLUMN scanner_lock_created_by UUID REFERENCES users(id);

-- Create scanner_unlock_attempts table for audit logging
CREATE TABLE scanner_unlock_attempts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE,
  attempted_by UUID REFERENCES users(id),
  attempt_result TEXT NOT NULL CHECK (attempt_result IN ('SUCCESS', 'FAILED', 'INVALID_PIN')),
  ip_address TEXT,
  user_agent TEXT,
  device_info TEXT,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Add indexes for performance
CREATE INDEX idx_scanner_unlock_attempts_event_id ON scanner_unlock_attempts(event_id);
CREATE INDEX idx_scanner_unlock_attempts_created_at ON scanner_unlock_attempts(created_at);
CREATE INDEX idx_scanner_unlock_attempts_result ON scanner_unlock_attempts(attempt_result);

-- Add RLS policies for scanner_unlock_attempts
ALTER TABLE scanner_unlock_attempts ENABLE ROW LEVEL SECURITY;

-- Policies for scanner_unlock_attempts
CREATE POLICY "Users can view scanner unlock attempts in their organization" ON scanner_unlock_attempts
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM users 
      WHERE users.id = auth.uid() 
      AND users.organization_id = (
        SELECT organization_id FROM events WHERE events.id = scanner_unlock_attempts.event_id
      )
    )
  );

CREATE POLICY "Users can insert scanner unlock attempts in their organization" ON scanner_unlock_attempts
  FOR INSERT WITH CHECK (
    EXISTS (
      SELECT 1 FROM users 
      WHERE users.id = auth.uid() 
      AND users.organization_id = (
        SELECT organization_id FROM events WHERE events.id = scanner_unlock_attempts.event_id
      )
    )
  );

-- Admin override policies (for users with admin privileges)
CREATE POLICY "Admin can view all scanner unlock attempts" ON scanner_unlock_attempts
  FOR SELECT USING (
    EXISTS (
      SELECT 1 FROM users 
      WHERE users.id = auth.uid() 
      AND users.organization_id IS NULL
    )
  );

CREATE POLICY "Admin can manage all scanner unlock attempts" ON scanner_unlock_attempts
  FOR ALL USING (
    EXISTS (
      SELECT 1 FROM users 
      WHERE users.id = auth.uid() 
      AND users.organization_id IS NULL
    )
  );

-- Create function to clean up scanner lock when event ends
CREATE OR REPLACE FUNCTION cleanup_expired_scanner_locks()
RETURNS void AS $$
BEGIN
  -- Disable scanner locks for events that ended more than 24 hours ago
  UPDATE events 
  SET 
    scanner_lock_enabled = FALSE,
    scanner_pin_hash = NULL,
    scanner_lock_created_at = NULL,
    scanner_lock_created_by = NULL
  WHERE 
    scanner_lock_enabled = TRUE 
    AND start_time < NOW() - INTERVAL '24 hours';
END;
$$ LANGUAGE plpgsql;

-- Create a function to be called when setting up scanner lock
CREATE OR REPLACE FUNCTION setup_scanner_lock(
  p_event_id UUID,
  p_pin_hash TEXT
) RETURNS BOOLEAN AS $$
BEGIN
  -- Update the event with scanner lock settings
  UPDATE events 
  SET 
    scanner_lock_enabled = TRUE,
    scanner_pin_hash = p_pin_hash,
    scanner_lock_created_at = NOW(),
    scanner_lock_created_by = auth.uid()
  WHERE id = p_event_id;
  
  -- Return true if update was successful
  RETURN FOUND;
END;
$$ LANGUAGE plpgsql;

-- Create a function to verify scanner PIN
CREATE OR REPLACE FUNCTION verify_scanner_pin(
  p_event_id UUID,
  p_pin_hash TEXT
) RETURNS BOOLEAN AS $$
DECLARE
  stored_hash TEXT;
BEGIN
  -- Get the stored PIN hash
  SELECT scanner_pin_hash INTO stored_hash
  FROM events
  WHERE id = p_event_id AND scanner_lock_enabled = TRUE;
  
  -- Return true if hashes match
  RETURN stored_hash = p_pin_hash;
END;
$$ LANGUAGE plpgsql;

-- Create a function to disable scanner lock
CREATE OR REPLACE FUNCTION disable_scanner_lock(
  p_event_id UUID
) RETURNS BOOLEAN AS $$
BEGIN
  -- Update the event to disable scanner lock
  UPDATE events 
  SET 
    scanner_lock_enabled = FALSE,
    scanner_pin_hash = NULL,
    scanner_lock_created_at = NULL,
    scanner_lock_created_by = NULL
  WHERE id = p_event_id;
  
  -- Return true if update was successful
  RETURN FOUND;
END;
$$ LANGUAGE plpgsql;