-- Migration: Update tablos table ID from SERIAL to random 24-character string
-- This migration changes the tablos.id column from SERIAL to TEXT with random 24-character string IDs

-- Step 1: Create function to generate random 24-character strings
CREATE OR REPLACE FUNCTION generate_random_string(length INTEGER DEFAULT 24)
RETURNS TEXT
LANGUAGE plpgsql
AS $$
DECLARE
    chars TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    result TEXT := '';
    i INTEGER := 0;
BEGIN
    FOR i IN 1..length LOOP
        result := result || substr(chars, floor(random() * length(chars) + 1)::INTEGER, 1);
    END LOOP;
    RETURN result;
END;
$$;

-- Step 2: Drop existing foreign key constraints
ALTER TABLE tablo_invites DROP CONSTRAINT IF EXISTS fk_tablo_invitations_tablo_id;
ALTER TABLE tablo_access DROP CONSTRAINT IF EXISTS fk_tablo_access_tablo_id;

-- Step 3: Drop the trigger that creates tablo_access records
DROP TRIGGER IF EXISTS trigger_create_tablo_access ON tablos;

-- Step 4: Create temporary columns for the new ID structure
ALTER TABLE tablos ADD COLUMN new_id TEXT;
ALTER TABLE tablo_invites ADD COLUMN new_tablo_id TEXT;
ALTER TABLE tablo_access ADD COLUMN new_tablo_id TEXT;

-- Step 5: Generate new random IDs for existing tablos
UPDATE tablos SET new_id = generate_random_string(24);

-- Step 6: Update foreign key references
UPDATE tablo_invites SET new_tablo_id = (
    SELECT new_id FROM tablos WHERE tablos.id = tablo_invites.tablo_id
);

UPDATE tablo_access SET new_tablo_id = (
    SELECT new_id FROM tablos WHERE tablos.id = tablo_access.tablo_id
);

-- Step 7: Drop old columns
ALTER TABLE tablo_invites DROP COLUMN tablo_id CASCADE;
ALTER TABLE tablo_access DROP COLUMN tablo_id CASCADE;
ALTER TABLE tablos DROP COLUMN id CASCADE;


-- Step 8: Rename new columns to original names
ALTER TABLE tablos RENAME COLUMN new_id TO id;
ALTER TABLE tablo_invites RENAME COLUMN new_tablo_id TO tablo_id;
ALTER TABLE tablo_access RENAME COLUMN new_tablo_id TO tablo_id;

-- Step 9: Add constraints and indexes
ALTER TABLE tablos ADD PRIMARY KEY (id);
ALTER TABLE tablos ALTER COLUMN id SET NOT NULL;
ALTER TABLE tablos ALTER COLUMN id SET DEFAULT generate_random_string(24);

-- Step 10: Re-add foreign key constraints
ALTER TABLE tablo_invites 
ADD CONSTRAINT fk_tablo_invitations_tablo_id 
FOREIGN KEY (tablo_id) REFERENCES tablos(id) ON DELETE CASCADE;

ALTER TABLE tablo_access 
ADD CONSTRAINT fk_tablo_access_tablo_id 
FOREIGN KEY (tablo_id) REFERENCES tablos(id) ON DELETE CASCADE;

-- Step 11: Ensure NOT NULL constraints on foreign keys
ALTER TABLE tablo_invites ALTER COLUMN tablo_id SET NOT NULL;
ALTER TABLE tablo_access ALTER COLUMN tablo_id SET NOT NULL;

-- Step 12: Recreate the trigger function with updated signature
CREATE OR REPLACE FUNCTION create_tablo_access_for_owner()
RETURNS TRIGGER
SECURITY DEFINER
AS $$
BEGIN
    -- Insert a tablo_access record for the tablo owner
    INSERT INTO tablo_access (
        tablo_id,
        user_id,
        granted_by,
        is_active,
        is_admin
    ) VALUES (
        NEW.id,           -- tablo_id: the newly created tablo's id (now TEXT)
        NEW.owner_id,     -- user_id: the tablo owner gets access
        NEW.owner_id,     -- granted_by: self-granted by the owner
        TRUE,             -- is_active: access is active
        TRUE              -- is_admin: owner has admin privileges
    );
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Step 13: Recreate the trigger
CREATE TRIGGER trigger_create_tablo_access
    AFTER INSERT ON tablos
    FOR EACH ROW
    EXECUTE FUNCTION create_tablo_access_for_owner();

-- Step 14: Add comment to document the changes
COMMENT ON FUNCTION generate_random_string(INTEGER) IS 
    'Generates a random alphanumeric string of specified length (default 24 characters)';

COMMENT ON COLUMN tablos.id IS 
    'Primary key: random 24-character alphanumeric string';

COMMENT ON COLUMN tablo_invites.tablo_id IS 
    'Foreign key reference to tablos.id (24-character string)';

COMMENT ON COLUMN tablo_access.tablo_id IS 
    'Foreign key reference to tablos.id (24-character string)';
