-- =====================================================
-- Migration: Device Management System Cleanup
-- Date: 2025-01-03
-- Purpose: Consolidate device tracking into single source of truth
-- =====================================================

-- STEP 1: Backup existing data
-- =====================================================
CREATE TABLE IF NOT EXISTS backup_device_data_20250103 AS
SELECT 
    'activations' as source_table,
    a.id,
    a.license_id,
    COALESCE(a.device_name, a.machine_id) as device_name,
    a.hardware_hash as hardware_fingerprint,
    a.first_seen as first_activated_at,
    a.last_seen as last_seen_at,
    a.is_active,
    a.os_info,
    a.app_version
FROM activations a
UNION ALL
SELECT 
    'device_registrations' as source_table,
    dr.id,
    dr.license_id,
    dr.device_name,
    dr.hardware_id as hardware_fingerprint,
    dr.first_seen as first_activated_at,
    dr.last_seen as last_seen_at,
    dr.is_active,
    dr.operating_system::jsonb as os_info,
    NULL as app_version
FROM device_registrations dr;

-- STEP 2: Standardize device_registrations table
-- =====================================================
-- Add missing columns to device_registrations
ALTER TABLE device_registrations 
    ADD COLUMN IF NOT EXISTS hardware_fingerprint VARCHAR(255),
    ADD COLUMN IF NOT EXISTS app_version VARCHAR(20),
    ADD COLUMN IF NOT EXISTS metadata JSONB DEFAULT '{}',
    ADD COLUMN IF NOT EXISTS first_activated_at TIMESTAMP WITH TIME ZONE,
    ADD COLUMN IF NOT EXISTS last_seen_at TIMESTAMP WITH TIME ZONE;

-- Migrate existing hardware_id to hardware_fingerprint
UPDATE device_registrations 
SET hardware_fingerprint = hardware_id 
WHERE hardware_fingerprint IS NULL AND hardware_id IS NOT NULL;

-- Migrate timestamp columns
UPDATE device_registrations 
SET first_activated_at = first_seen,
    last_seen_at = last_seen
WHERE first_activated_at IS NULL OR last_seen_at IS NULL;

-- STEP 3: Migrate data from activations to device_registrations
-- =====================================================
-- Insert activations that don't exist in device_registrations
INSERT INTO device_registrations (
    license_id,
    hardware_fingerprint,
    device_name,
    device_type,
    operating_system,
    first_activated_at,
    last_seen_at,
    is_active,
    ip_address,
    user_agent,
    app_version,
    metadata
)
SELECT 
    a.license_id,
    a.hardware_hash as hardware_fingerprint,
    COALESCE(a.device_name, a.machine_id) as device_name,
    CASE 
        WHEN a.os_info->>'os' ILIKE '%windows%' THEN 'desktop'
        WHEN a.os_info->>'os' ILIKE '%mac%' THEN 'desktop'
        WHEN a.os_info->>'os' ILIKE '%linux%' THEN 'desktop'
        ELSE 'unknown'
    END as device_type,
    a.os_info->>'os' as operating_system,
    a.first_seen,
    a.last_seen,
    a.is_active,
    NULL as ip_address,
    NULL as user_agent,
    a.app_version,
    a.os_info as metadata
FROM activations a
WHERE NOT EXISTS (
    SELECT 1 FROM device_registrations dr 
    WHERE dr.license_id = a.license_id 
    AND dr.hardware_fingerprint = a.hardware_hash
);

-- Update existing device_registrations with latest data from activations
UPDATE device_registrations dr
SET 
    last_seen_at = GREATEST(dr.last_seen_at, a.last_seen),
    is_active = a.is_active,
    app_version = COALESCE(a.app_version, dr.app_version),
    metadata = COALESCE(dr.metadata, '{}')::jsonb || COALESCE(a.os_info, '{}')::jsonb
FROM activations a
WHERE dr.license_id = a.license_id 
AND dr.hardware_fingerprint = a.hardware_hash
AND a.last_seen > dr.last_seen_at;

-- STEP 4: Standardize licenses table
-- =====================================================
-- Remove duplicate device limit columns, keep only device_limit
ALTER TABLE licenses DROP COLUMN IF EXISTS max_devices;
ALTER TABLE licenses DROP COLUMN IF EXISTS max_activations;

-- Ensure device_limit has proper constraints
ALTER TABLE licenses 
    DROP CONSTRAINT IF EXISTS licenses_device_limit_check,
    ADD CONSTRAINT licenses_device_limit_check CHECK (device_limit >= 1);

-- Rename max_concurrent_sessions to concurrent_sessions_limit for clarity
ALTER TABLE licenses 
    RENAME COLUMN max_concurrent_sessions TO concurrent_sessions_limit;

-- Update constraint to reference device_limit
ALTER TABLE licenses
    DROP CONSTRAINT IF EXISTS check_concurrent_sessions,
    ADD CONSTRAINT check_concurrent_sessions CHECK (concurrent_sessions_limit <= device_limit);

-- STEP 5: Clean up session tables
-- =====================================================
-- Consolidate into single license_sessions table
-- First, backup existing session data
CREATE TABLE IF NOT EXISTS backup_sessions_20250103 AS
SELECT 
    id,
    license_id,
    license_key,
    session_id,
    username,
    computer_name,
    hardware_id,
    ip_address,
    user_agent,
    app_version,
    started_at,
    last_heartbeat,
    ended_at,
    is_active
FROM sessions;

-- Add missing columns to license_sessions
ALTER TABLE license_sessions
    ADD COLUMN IF NOT EXISTS device_registration_id INTEGER REFERENCES device_registrations(id),
    ADD COLUMN IF NOT EXISTS ended_at TIMESTAMP WITH TIME ZONE,
    ADD COLUMN IF NOT EXISTS end_reason VARCHAR(50),
    ADD COLUMN IF NOT EXISTS user_agent TEXT;

-- Link license_sessions to device_registrations
UPDATE license_sessions ls
SET device_registration_id = dr.id
FROM device_registrations dr
WHERE ls.license_id = dr.license_id 
AND ls.hardware_id = dr.hardware_fingerprint
AND ls.device_registration_id IS NULL;

-- STEP 6: Create indexes for performance
-- =====================================================
CREATE INDEX IF NOT EXISTS idx_device_registrations_license_fingerprint 
    ON device_registrations(license_id, hardware_fingerprint);
CREATE INDEX IF NOT EXISTS idx_device_registrations_active 
    ON device_registrations(license_id, is_active) WHERE is_active = true;
CREATE INDEX IF NOT EXISTS idx_device_registrations_last_seen 
    ON device_registrations(last_seen_at DESC);

-- STEP 7: Drop old columns (after verification)
-- =====================================================
-- These will be dropped after confirming migration success
ALTER TABLE device_registrations 
    DROP COLUMN IF EXISTS hardware_id,
    DROP COLUMN IF EXISTS first_seen,
    DROP COLUMN IF EXISTS last_seen;

-- STEP 8: Create views for backwards compatibility (temporary)
-- =====================================================
CREATE OR REPLACE VIEW v_activations AS
SELECT 
    id,
    license_id,
    device_name as machine_id,
    device_name,
    hardware_fingerprint as hardware_hash,
    first_activated_at as activation_date,
    first_activated_at as first_seen,
    last_seen_at as last_seen,
    last_seen_at as last_heartbeat,
    is_active,
    metadata as os_info,
    operating_system,
    app_version,
    ip_address,
    user_agent,
    device_type,
    deactivated_at,
    deactivated_by
FROM device_registrations;

-- STEP 9: Update system_api_key usage tracking
-- =====================================================
UPDATE system_api_key 
SET last_used_at = CURRENT_TIMESTAMP,
    usage_count = usage_count + 1
WHERE id = 1;

-- STEP 10: Add audit log entry for migration
-- =====================================================
INSERT INTO audit_log (
    timestamp,
    username,
    action,
    entity_type,
    entity_id,
    additional_info
) VALUES (
    CURRENT_TIMESTAMP,
    'system',
    'device_management_migration',
    'database',
    0,
    'Consolidated device management system - merged activations into device_registrations'
);

-- Summary of changes:
-- 1. Consolidated device tracking into device_registrations table
-- 2. Removed duplicate columns: max_devices, max_activations
-- 3. Standardized on device_limit column
-- 4. Renamed max_concurrent_sessions to concurrent_sessions_limit
-- 5. Added proper foreign key relationships
-- 6. Created backwards compatibility view for activations
-- 7. Improved indexing for performance