-- ============================================================================
-- Nxtgauge Database Complete Migration
-- Version: 20260415000000
-- This migration performs a COMPLETE schema transformation
-- NO FALLBACKS - This is a one-way migration
-- ============================================================================

BEGIN;

-- ============================================================================
-- PHASE 1: Create New Core Tables
-- ============================================================================

-- 1.1 user_sessions (new)
CREATE TABLE IF NOT EXISTS user_sessions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    session_token TEXT UNIQUE NOT NULL,
    ip_address TEXT,
    user_agent TEXT,
    expires_at TIMESTAMPTZ NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_user_sessions_user_id ON user_sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_user_sessions_token ON user_sessions(session_token);
CREATE INDEX IF NOT EXISTS idx_user_sessions_expires ON user_sessions(expires_at);

-- 1.2 user_role_profiles (NEW ROOT - CRITICAL)
CREATE TABLE IF NOT EXISTS user_role_profiles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    role_key VARCHAR(50) NOT NULL,
    display_name TEXT,
    bio TEXT,
    location TEXT,
    avatar_url TEXT,
    phone TEXT,
    email TEXT,
    status VARCHAR(50) NOT NULL DEFAULT 'ACTIVE',
    verification_status VARCHAR(50) DEFAULT 'PENDING',
    approval_status VARCHAR(50) DEFAULT 'PENDING',
    rejection_reason TEXT,
    approved_at TIMESTAMPTZ,
    verified_at TIMESTAMPTZ,
    is_profile_public BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    UNIQUE(user_id, role_key)
);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_user_id ON user_role_profiles(user_id);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_role_key ON user_role_profiles(role_key);
CREATE INDEX IF NOT EXISTS idx_user_role_profiles_status ON user_role_profiles(status);

-- ============================================================================
-- PHASE 2: Backfill user_role_profiles from ALL existing profile tables
-- ============================================================================

-- Backfill from photographer_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'photographer', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM photographer_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'photographer');

-- Backfill from tutor_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'tutor', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM tutor_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'tutor');

-- Backfill from makeup_artist_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'makeup_artist', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM makeup_artist_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'makeup_artist');

-- Backfill from developer_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'developer', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM developer_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'developer');

-- Backfill from video_editor_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'video_editor', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM video_editor_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'video_editor');

-- Backfill from graphic_designer_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'graphic_designer', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM graphic_designer_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'graphic_designer');

-- Backfill from social_media_manager_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'social_media_manager', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM social_media_manager_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'social_media_manager');

-- Backfill from fitness_trainer_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'fitness_trainer', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM fitness_trainer_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'fitness_trainer');

-- Backfill from catering_service_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'catering_service', p.business_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM catering_service_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'catering_service');

-- Backfill from ugc_content_creator_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, approval_status, rejection_reason, approved_at, created_at, updated_at)
SELECT gen_random_uuid(), p.user_id, 'ugc_content_creator', p.display_name, p.bio, p.location, 
       COALESCE(p.status, 'ACTIVE'), COALESCE(p.status, 'PENDING'), p.rejection_reason, p.approved_at, p.created_at, COALESCE(p.updated_at, NOW())
FROM ugc_content_creator_profiles p
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = p.user_id AND urp.role_key = 'ugc_content_creator');

-- Backfill from company_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, created_at, updated_at)
SELECT gen_random_uuid(), cp.user_id, 'company', cp.company_name, cp.bio, NULL, 
       COALESCE(cp.status, 'ACTIVE'), cp.created_at, COALESCE(cp.updated_at, NOW())
FROM company_profiles cp
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = cp.user_id AND urp.role_key = 'company');

-- Backfill from customer_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, location, status, created_at, updated_at)
SELECT gen_random_uuid(), cp.user_id, 'customer', COALESCE(cp.full_name, ''), cp.city, 
       COALESCE(cp.status, 'ACTIVE'), cp.created_at, COALESCE(cp.updated_at, NOW())
FROM customer_profiles cp
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = cp.user_id AND urp.role_key = 'customer');

-- Backfill from job_seeker_profiles
INSERT INTO user_role_profiles (id, user_id, role_key, display_name, bio, location, status, created_at, updated_at)
SELECT gen_random_uuid(), jsp.user_id, 'candidate', COALESCE(jsp.full_name, ''), jsp.bio, jsp.location, 
       COALESCE(jsp.status, 'ACTIVE'), jsp.created_at, COALESCE(jsp.updated_at, NOW())
FROM job_seeker_profiles jsp
WHERE NOT EXISTS (SELECT 1 FROM user_role_profiles urp WHERE urp.user_id = jsp.user_id AND urp.role_key = 'candidate');

-- ============================================================================
-- PHASE 3: Update Extension Tables to Use user_role_profile_id
-- ============================================================================

-- Add user_role_profile_id column to ALL extension tables
ALTER TABLE photographer_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE tutor_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE makeup_artist_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE developer_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE video_editor_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE graphic_designer_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE social_media_manager_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE fitness_trainer_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE catering_service_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE ugc_content_creator_profiles ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;

-- Backfill user_role_profile_id for photographer_profiles
UPDATE photographer_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'photographer' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for tutor_profiles
UPDATE tutor_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'tutor' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for makeup_artist_profiles
UPDATE makeup_artist_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'makeup_artist' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for developer_profiles
UPDATE developer_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'developer' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for video_editor_profiles
UPDATE video_editor_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'video_editor' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for graphic_designer_profiles
UPDATE graphic_designer_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'graphic_designer' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for social_media_manager_profiles
UPDATE social_media_manager_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'social_media_manager' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for fitness_trainer_profiles
UPDATE fitness_trainer_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'fitness_trainer' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for catering_service_profiles
UPDATE catering_service_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'catering_service' AND p.user_role_profile_id IS NULL;

-- Backfill user_role_profile_id for ugc_content_creator_profiles
UPDATE ugc_content_creator_profiles p SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE p.user_id = urp.user_id AND urp.role_key = 'ugc_content_creator' AND p.user_role_profile_id IS NULL;

-- ============================================================================
-- PHASE 4: Remove Forbidden External Portfolio Links
-- ============================================================================

ALTER TABLE developer_profiles DROP COLUMN IF EXISTS github_url;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS portfolio_url;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS reel_url;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS portfolio_url;
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS portfolio_url;

-- ============================================================================
-- PHASE 5: Update Portfolio Tables
-- ============================================================================

-- Add user_role_profile_id to portfolio_items
ALTER TABLE portfolio_items ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
ALTER TABLE portfolio_items ADD COLUMN IF NOT EXISTS display_order INTEGER DEFAULT 0;

-- Backfill portfolio_items from professionals
UPDATE portfolio_items pi SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE pi.professional_id IS NOT NULL 
  AND urp.user_id = (SELECT user_id FROM professionals p WHERE p.id = pi.professional_id);

-- Update remaining using user_id
UPDATE portfolio_items pi SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE pi.user_id IS NOT NULL AND pi.user_role_profile_id IS NULL
  AND EXISTS (SELECT 1 FROM user_role_profiles urp2 WHERE urp2.user_id = pi.user_id AND urp2.role_key = pi.profession_key);

-- Add user_role_profile_id to services
ALTER TABLE services ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;

-- Backfill services
UPDATE services s SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE s.professional_id IS NOT NULL 
  AND urp.user_id = (SELECT user_id FROM professionals p WHERE p.id = s.professional_id);

UPDATE services s SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE s.user_id IS NOT NULL AND s.user_role_profile_id IS NULL
  AND EXISTS (SELECT 1 FROM user_role_profiles urp2 WHERE urp2.user_id = s.user_id AND urp2.role_key = s.profession_key);

-- ============================================================================
-- PHASE 6: Rename Tables
-- ============================================================================

-- Rename applications -> job_applications
ALTER TABLE applications RENAME TO job_applications;

-- Rename requirements -> leads
ALTER TABLE requirements RENAME TO leads;

-- Rename coupon_uses -> coupon_redemptions
ALTER TABLE coupon_uses RENAME TO coupon_redemptions;

-- ============================================================================
-- PHASE 7: Create New Domain Tables
-- ============================================================================

-- 7.1 verification_requests
CREATE TABLE IF NOT EXISTS verification_requests (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_role_profile_id UUID REFERENCES user_role_profiles(id),
    verification_type VARCHAR(50) NOT NULL DEFAULT 'IDENTITY',
    status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
    submitted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    reviewed_at TIMESTAMPTZ,
    reviewed_by_user_id UUID REFERENCES users(id),
    remarks TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.2 verification_documents
CREATE TABLE IF NOT EXISTS verification_documents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    verification_request_id UUID NOT NULL REFERENCES verification_requests(id) ON DELETE CASCADE,
    document_type VARCHAR(100) NOT NULL,
    file_url TEXT NOT NULL,
    file_name TEXT,
    mime_type TEXT,
    status VARCHAR(50) DEFAULT 'PENDING',
    uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    reviewed_at TIMESTAMPTZ,
    reviewed_by_user_id UUID REFERENCES users(id),
    remarks TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.3 verification_logs
CREATE TABLE IF NOT EXISTS verification_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    verification_request_id UUID NOT NULL REFERENCES verification_requests(id),
    action VARCHAR(50) NOT NULL,
    old_status VARCHAR(50),
    new_status VARCHAR(50),
    acted_by_user_id UUID REFERENCES users(id),
    remarks TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.4 approval_requests
CREATE TABLE IF NOT EXISTS approval_requests (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    entity_type VARCHAR(50) NOT NULL,
    entity_id UUID NOT NULL,
    approval_type VARCHAR(50),
    status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
    submitted_by_user_id UUID REFERENCES users(id),
    reviewed_by_user_id UUID REFERENCES users(id),
    submitted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    reviewed_at TIMESTAMPTZ,
    remarks TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.5 approval_logs
CREATE TABLE IF NOT EXISTS approval_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    approval_request_id UUID NOT NULL REFERENCES approval_requests(id),
    action VARCHAR(50) NOT NULL,
    old_status VARCHAR(50),
    new_status VARCHAR(50),
    acted_by_user_id UUID REFERENCES users(id),
    remarks TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.6 audit_logs
CREATE TABLE IF NOT EXISTS audit_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    actor_user_id UUID REFERENCES users(id),
    actor_employee_id UUID,
    actor_type VARCHAR(50),
    action VARCHAR(100) NOT NULL,
    entity_type VARCHAR(100),
    entity_id UUID,
    entity_label TEXT,
    module_key VARCHAR(100),
    source_type VARCHAR(50),
    source_id UUID,
    request_id UUID,
    correlation_id UUID,
    ip_address TEXT,
    user_agent TEXT,
    status VARCHAR(50) NOT NULL DEFAULT 'SUCCESS',
    summary TEXT,
    metadata_json JSONB,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.7 audit_log_changes
CREATE TABLE IF NOT EXISTS audit_log_changes (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    audit_log_id UUID NOT NULL REFERENCES audit_logs(id) ON DELETE CASCADE,
    field_name TEXT NOT NULL,
    old_value_text TEXT,
    new_value_text TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_audit_logs_actor ON audit_logs(actor_user_id);
CREATE INDEX IF NOT EXISTS idx_audit_logs_entity ON audit_logs(entity_type, entity_id);
CREATE INDEX IF NOT EXISTS idx_audit_logs_module ON audit_logs(module_key);
CREATE INDEX IF NOT EXISTS idx_audit_logs_created ON audit_logs(created_at);

-- 7.8 orders
CREATE TABLE IF NOT EXISTS orders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id),
    order_type VARCHAR(50) NOT NULL DEFAULT 'PACKAGE',
    subtotal_inr INTEGER NOT NULL DEFAULT 0,
    discount_inr INTEGER NOT NULL DEFAULT 0,
    tax_inr INTEGER NOT NULL DEFAULT 0,
    total_inr INTEGER NOT NULL DEFAULT 0,
    status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.9 order_items
CREATE TABLE IF NOT EXISTS order_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    order_id UUID NOT NULL REFERENCES orders(id) ON DELETE CASCADE,
    item_type VARCHAR(50) NOT NULL,
    item_id UUID,
    item_name TEXT NOT NULL,
    quantity INTEGER NOT NULL DEFAULT 1,
    unit_price_inr INTEGER NOT NULL,
    total_price_inr INTEGER NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.10 payment_gateway_configs
CREATE TABLE IF NOT EXISTS payment_gateway_configs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    gateway_key VARCHAR(50) NOT NULL,
    display_name VARCHAR(255),
    config_json JSONB,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.11 payment_transactions
CREATE TABLE IF NOT EXISTS payment_transactions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    payment_id UUID NOT NULL REFERENCES payments(id),
    transaction_type VARCHAR(50) NOT NULL,
    provider_reference TEXT,
    request_payload_json JSONB,
    response_payload_json JSONB,
    status VARCHAR(50) NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.12 tax_rules
CREATE TABLE IF NOT EXISTS tax_rules (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    tax_type VARCHAR(50) NOT NULL,
    tax_rate DECIMAL(5,2) NOT NULL,
    applies_to VARCHAR(50),
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.13 kb_sections
CREATE TABLE IF NOT EXISTS kb_sections (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    category_id UUID NOT NULL REFERENCES kb_categories(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    slug VARCHAR(255) NOT NULL,
    description TEXT,
    display_order INTEGER DEFAULT 0,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.14 kb_article_feedback
CREATE TABLE IF NOT EXISTS kb_article_feedback (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    article_id UUID NOT NULL REFERENCES kb_articles(id) ON DELETE CASCADE,
    user_id UUID REFERENCES users(id),
    is_helpful BOOLEAN,
    feedback_text TEXT,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.15 notification_templates
CREATE TABLE IF NOT EXISTS notification_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    template_key VARCHAR(100) NOT NULL UNIQUE,
    channel VARCHAR(50) NOT NULL DEFAULT 'EMAIL',
    title_template TEXT,
    body_template TEXT,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.16 smtp_configs
CREATE TABLE IF NOT EXISTS smtp_configs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    provider_name VARCHAR(100),
    host VARCHAR(255),
    port INTEGER,
    username TEXT,
    encryption_mode VARCHAR(20),
    from_name VARCHAR(255),
    from_email VARCHAR(255),
    is_default BOOLEAN DEFAULT false,
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- 7.17 dashboard_widgets
CREATE TABLE IF NOT EXISTS dashboard_widgets (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    dashboard_config_id UUID NOT NULL REFERENCES dashboard_configs(id) ON DELETE CASCADE,
    widget_key VARCHAR(100) NOT NULL,
    widget_title VARCHAR(255),
    config_json JSONB,
    display_order INTEGER DEFAULT 0,
    width_units INTEGER DEFAULT 1,
    height_units INTEGER DEFAULT 1,
    is_visible BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- ============================================================================
-- PHASE 8: Update Existing Tables
-- ============================================================================

-- Update users table
ALTER TABLE users ADD COLUMN IF NOT EXISTS account_type TEXT DEFAULT 'INDIVIDUAL';
ALTER TABLE users ADD COLUMN IF NOT EXISTS last_login_at TIMESTAMPTZ;
ALTER TABLE users ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
UPDATE users SET updated_at = COALESCE(updated_at, created_at, NOW()) WHERE updated_at IS NULL;

-- Update roles table
ALTER TABLE roles ADD COLUMN IF NOT EXISTS description TEXT;
ALTER TABLE roles ADD COLUMN IF NOT EXISTS can_approve_requests BOOLEAN DEFAULT false;
ALTER TABLE roles ADD COLUMN IF NOT EXISTS can_manage_system_settings BOOLEAN DEFAULT false;

-- Update departments table
ALTER TABLE departments ADD COLUMN IF NOT EXISTS code VARCHAR(64);
ALTER TABLE departments ADD COLUMN IF NOT EXISTS description TEXT;
ALTER TABLE departments ADD COLUMN IF NOT EXISTS department_head VARCHAR(255);
ALTER TABLE departments ADD COLUMN IF NOT EXISTS department_email VARCHAR(255);
ALTER TABLE departments ADD COLUMN IF NOT EXISTS visibility VARCHAR(20) DEFAULT 'INTERNAL';
ALTER TABLE departments ADD COLUMN IF NOT EXISTS transfers_enabled BOOLEAN DEFAULT false;
ALTER TABLE departments ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
UPDATE departments SET updated_at = COALESCE(updated_at, created_at, NOW()) WHERE updated_at IS NULL;

-- Update designations table
ALTER TABLE designations ADD COLUMN IF NOT EXISTS code VARCHAR(64);
ALTER TABLE designations ADD COLUMN IF NOT EXISTS department_id UUID REFERENCES departments(id);
ALTER TABLE designations ADD COLUMN IF NOT EXISTS description TEXT;
ALTER TABLE designations ADD COLUMN IF NOT EXISTS level VARCHAR(100);
ALTER TABLE designations ADD COLUMN IF NOT EXISTS can_manage_team BOOLEAN DEFAULT false;
ALTER TABLE designations ADD COLUMN IF NOT EXISTS can_approve BOOLEAN DEFAULT false;
ALTER TABLE designations ADD COLUMN IF NOT EXISTS is_active BOOLEAN DEFAULT true;
ALTER TABLE designations ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
UPDATE designations SET updated_at = COALESCE(updated_at, created_at, NOW()) WHERE updated_at IS NULL;

-- Update employees table
ALTER TABLE employees ADD COLUMN IF NOT EXISTS joining_date DATE;
ALTER TABLE employees ADD COLUMN IF NOT EXISTS employment_status VARCHAR(50) DEFAULT 'ACTIVE';
ALTER TABLE employees ADD COLUMN IF NOT EXISTS manager_employee_id UUID REFERENCES employees(id);
ALTER TABLE employees ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
UPDATE employees SET updated_at = COALESCE(updated_at, created_at, NOW()) WHERE updated_at IS NULL;

-- Update lead_requests table
ALTER TABLE lead_requests ADD COLUMN IF NOT EXISTS user_role_profile_id UUID;
UPDATE lead_requests lr SET user_role_profile_id = urp.id
FROM user_role_profiles urp 
WHERE lr.professional_id IS NOT NULL 
  AND urp.user_id = (SELECT user_id FROM professionals p WHERE p.id = lr.professional_id);
ALTER TABLE lead_requests ADD COLUMN IF NOT EXISTS remarks TEXT;
ALTER TABLE lead_requests ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();

-- Update job_applications table
ALTER TABLE job_applications ADD COLUMN IF NOT EXISTS applicant_user_id UUID;
UPDATE job_applications ja SET applicant_user_id = (
    SELECT user_id FROM job_seeker_profiles jsp WHERE jsp.id = ja.job_seeker_id
);
ALTER TABLE job_applications ADD COLUMN IF NOT EXISTS cover_note TEXT;
ALTER TABLE job_applications DROP COLUMN IF EXISTS job_seeker_id;
ALTER TABLE job_applications DROP COLUMN IF EXISTS cover_letter;
ALTER TABLE job_applications DROP COLUMN IF EXISTS resume_url;
ALTER TABLE job_applications DROP COLUMN IF EXISTS contact_viewed;

-- Update leads table (formerly requirements)
ALTER TABLE leads ADD COLUMN IF NOT EXISTS created_by_user_id UUID;
UPDATE leads l SET created_by_user_id = (
    SELECT user_id FROM customer_profiles cp WHERE cp.id = l.customer_id
);
ALTER TABLE leads ADD COLUMN IF NOT EXISTS required_date DATE;
ALTER TABLE leads ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
ALTER TABLE leads DROP COLUMN IF EXISTS customer_id;

-- Update jobs table
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS posted_by_user_id UUID;
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS mode_of_work VARCHAR(50);
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS budget_inr INTEGER;
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS salary_range_json JSONB;
ALTER TABLE jobs ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();
UPDATE jobs SET updated_at = COALESCE(updated_at, created_at, NOW()) WHERE updated_at IS NULL;

-- Update tracecoin_wallets
ALTER TABLE tracecoin_wallets RENAME COLUMN balance TO current_balance;
ALTER TABLE tracecoin_wallets ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW();

-- Update tracecoin_ledger
ALTER TABLE tracecoin_ledger ADD COLUMN IF NOT EXISTS balance_after INTEGER;
ALTER TABLE tracecoin_ledger ADD COLUMN IF NOT EXISTS remarks TEXT;
ALTER TABLE tracecoin_ledger RENAME COLUMN type TO transaction_type;
ALTER TABLE tracecoin_ledger RENAME COLUMN reason TO reference_type;

-- Update coupons
ALTER TABLE coupons ADD COLUMN IF NOT EXISTS max_discount_inr INTEGER;
ALTER TABLE coupons ADD COLUMN IF NOT EXISTS min_order_value_inr INTEGER DEFAULT 0;
ALTER TABLE coupons ADD COLUMN IF NOT EXISTS valid_from TIMESTAMPTZ DEFAULT NOW();
ALTER TABLE coupons ADD COLUMN IF NOT EXISTS valid_to TIMESTAMPTZ;

-- Update coupon_redemptions
ALTER TABLE coupon_redemptions ADD COLUMN IF NOT EXISTS order_id UUID REFERENCES orders(id);
ALTER TABLE coupon_redemptions ADD COLUMN IF NOT EXISTS discount_amount_inr INTEGER;
ALTER TABLE coupon_redemptions RENAME COLUMN used_at TO redeemed_at;

-- Update invoices
ALTER TABLE invoices ADD COLUMN IF NOT EXISTS order_id UUID REFERENCES orders(id);
ALTER TABLE invoices ADD COLUMN IF NOT EXISTS discount_inr INTEGER DEFAULT 0;
ALTER TABLE invoices ADD COLUMN IF NOT EXISTS due_at TIMESTAMPTZ;
ALTER TABLE invoices ADD COLUMN IF NOT EXISTS paid_at TIMESTAMPTZ;

-- Update payments
ALTER TABLE payments ADD COLUMN IF NOT EXISTS payment_gateway_config_id UUID REFERENCES payment_gateway_configs(id);
ALTER TABLE payments ADD COLUMN IF NOT EXISTS payment_method VARCHAR(50);
ALTER TABLE payments ADD COLUMN IF NOT EXISTS currency_code VARCHAR(10) DEFAULT 'INR';
ALTER TABLE payments ADD COLUMN IF NOT EXISTS initiated_at TIMESTAMPTZ DEFAULT NOW();
ALTER TABLE payments ADD COLUMN IF NOT EXISTS completed_at TIMESTAMPTZ;

-- Update kb_articles
ALTER TABLE kb_articles ADD COLUMN IF NOT EXISTS section_id UUID REFERENCES kb_sections(id);
ALTER TABLE kb_articles ADD COLUMN IF NOT EXISTS article_type VARCHAR(50) DEFAULT 'HOW_TO';
ALTER TABLE kb_articles ADD COLUMN IF NOT EXISTS audience_type VARCHAR(50) DEFAULT 'ALL';
ALTER TABLE kb_articles RENAME COLUMN body TO content_markdown;
ALTER TABLE kb_articles RENAME COLUMN created_by TO author_user_id;

-- Update support_tickets
ALTER TABLE support_tickets ADD COLUMN IF NOT EXISTS created_by_user_id UUID;
UPDATE support_tickets SET created_by_user_id = user_id;
ALTER TABLE support_tickets RENAME COLUMN assigned_to TO assigned_to_user_id;
ALTER TABLE support_tickets ADD COLUMN IF NOT EXISTS related_entity_type VARCHAR(50);
ALTER TABLE support_tickets ADD COLUMN IF NOT EXISTS related_entity_id UUID;
ALTER TABLE support_tickets ADD COLUMN IF NOT EXISTS closed_at TIMESTAMPTZ;

-- Update support_ticket_messages
ALTER TABLE support_ticket_messages ADD COLUMN IF NOT EXISTS sender_user_id UUID;
UPDATE support_ticket_messages SET sender_user_id = sender_id;
ALTER TABLE support_ticket_messages RENAME COLUMN body TO message_body;
ALTER TABLE support_ticket_messages ADD COLUMN IF NOT EXISTS attachment_url TEXT;

-- Update notifications
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS channel VARCHAR(50) DEFAULT 'IN_APP';
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS related_entity_type VARCHAR(50);
ALTER TABLE notifications RENAME COLUMN reference_id TO related_entity_id;

-- Update reviews
ALTER TABLE reviews ADD COLUMN IF NOT EXISTS entity_type VARCHAR(50) DEFAULT 'professional';
ALTER TABLE reviews RENAME COLUMN customer_id TO reviewer_user_id;
ALTER TABLE reviews ADD COLUMN IF NOT EXISTS status VARCHAR(50) DEFAULT 'PUBLISHED';

-- ============================================================================
-- PHASE 9: Drop Deprecated Tables
-- ============================================================================

DROP TABLE IF EXISTS professionals CASCADE;
DROP TABLE IF EXISTS onboarding_submissions CASCADE;
DROP TABLE IF EXISTS onboarding_configs CASCADE;
DROP TABLE IF EXISTS onboarding_states CASCADE;
DROP TABLE IF EXISTS submission_documents CASCADE;

-- ============================================================================
-- PHASE 10: Drop Deprecated Columns from Extension Tables
-- ============================================================================

-- Drop old user_id columns from extension tables (AFTER backfilling user_role_profile_id)
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS user_id;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS user_id;

-- Drop old columns from portfolio_items
ALTER TABLE portfolio_items DROP COLUMN IF EXISTS professional_id;
ALTER TABLE portfolio_items DROP COLUMN IF EXISTS user_id;
ALTER TABLE portfolio_items DROP COLUMN IF EXISTS profession_key;

-- Drop old columns from services
ALTER TABLE services DROP COLUMN IF EXISTS professional_id;
ALTER TABLE services DROP COLUMN IF EXISTS user_id;
ALTER TABLE services DROP COLUMN IF EXISTS profession_key;

-- Drop old columns from lead_requests
ALTER TABLE lead_requests DROP COLUMN IF EXISTS professional_id;
ALTER TABLE lead_requests DROP COLUMN IF EXISTS requirement_id;

-- Drop old custom_data columns
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS custom_data;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS custom_data;

-- Drop old profile columns that are now in user_role_profiles
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE photographer_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE tutor_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE makeup_artist_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE developer_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE developer_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE video_editor_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE graphic_designer_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE social_media_manager_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE fitness_trainer_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE catering_service_profiles DROP COLUMN IF EXISTS approved_at;

ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS display_name;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS bio;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS location;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS status;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS rejection_reason;
ALTER TABLE ugc_content_creator_profiles DROP COLUMN IF EXISTS approved_at;

COMMIT;

-- ============================================================================
-- Migration Complete
-- ============================================================================
