-- =============================================================================
-- Life OS - R0 to R1 Data Migration (FIXED)
-- Source: lifeos_prod (R0 schema - actual)
-- Target: lifeos_dev (R1 schema)
-- 
-- PREREQUISITE: R1 schema must already be applied to lifeos_dev
-- RUN FROM: lifeos_dev database as postgres user
-- =============================================================================

CREATE EXTENSION IF NOT EXISTS dblink;

-- =============================================================================
-- 1. DOMAINS
-- R0: id, name, color, created_at
-- R1: + description, icon, sort_order, is_deleted, deleted_at, updated_at, search_vector
-- =============================================================================

INSERT INTO domains (id, name, color, sort_order, is_deleted, created_at, updated_at)
SELECT id, name, color,
    (ROW_NUMBER() OVER (ORDER BY created_at))::INTEGER * 10,
    false, created_at, created_at
FROM dblink('dbname=lifeos_prod', '
    SELECT id, name, color, created_at FROM domains
') AS r0(id UUID, name TEXT, color TEXT, created_at TIMESTAMPTZ);

-- =============================================================================
-- 2. AREAS
-- R0: id, domain_id, name, description, status, created_at
-- R1: + icon, color, sort_order, is_deleted, deleted_at, updated_at, search_vector
-- =============================================================================

INSERT INTO areas (id, domain_id, name, description, status, sort_order, is_deleted, created_at, updated_at)
SELECT id, domain_id, name, description, COALESCE(status, 'active'),
    (ROW_NUMBER() OVER (PARTITION BY domain_id ORDER BY created_at))::INTEGER * 10,
    false, created_at, created_at
FROM dblink('dbname=lifeos_prod', '
    SELECT id, domain_id, name, description, status, created_at FROM areas
') AS r0(id UUID, domain_id UUID, name TEXT, description TEXT, status TEXT, created_at TIMESTAMPTZ);

-- =============================================================================
-- 3. PROJECTS
-- R0: id, domain_id, name, description, status, priority, start_date,
--     target_date, completed_at, tags, created_at, updated_at, area_id
-- R1: + color, sort_order, is_deleted, deleted_at, search_vector
-- =============================================================================

INSERT INTO projects (id, domain_id, area_id, name, description, status, priority,
    start_date, target_date, completed_at, tags, sort_order, is_deleted, created_at, updated_at)
SELECT id, domain_id, area_id, name, description,
    COALESCE(status, 'active'), COALESCE(priority, 3),
    start_date, target_date, completed_at, tags,
    (ROW_NUMBER() OVER (PARTITION BY domain_id ORDER BY created_at))::INTEGER * 10,
    false, created_at, COALESCE(updated_at, created_at)
FROM dblink('dbname=lifeos_prod', '
    SELECT id, domain_id, area_id, name, description, status, priority,
        start_date, target_date, completed_at, tags, created_at, updated_at
    FROM projects
') AS r0(
    id UUID, domain_id UUID, area_id UUID, name TEXT, description TEXT,
    status TEXT, priority INTEGER, start_date DATE, target_date DATE,
    completed_at TIMESTAMPTZ, tags TEXT[], created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ
);

-- =============================================================================
-- 4. TASKS
-- R0: id, domain_id, project_id, parent_id, title, description, priority,
--     status, due_date, deadline, recurrence, tags, context, is_custom_context,
--     created_at, updated_at, completed_at
-- R1: + area_id, release_id, estimated_minutes, energy_required,
--       waiting_for_contact_id, waiting_since, import_batch_id,
--       sort_order, is_deleted, deleted_at, search_vector
-- NOTE: R0 has no area_id on tasks. Left NULL in R1.
-- =============================================================================

INSERT INTO tasks (id, domain_id, project_id, parent_id, title, description,
    priority, status, due_date, deadline, recurrence, tags, context,
    is_custom_context, sort_order, is_deleted, created_at, updated_at, completed_at)
SELECT id, domain_id, project_id, parent_id, title, description,
    COALESCE(priority, 3), COALESCE(status, 'open'),
    due_date, deadline, recurrence, tags, context,
    COALESCE(is_custom_context, false),
    (ROW_NUMBER() OVER (PARTITION BY project_id ORDER BY created_at))::INTEGER * 10,
    false, created_at, COALESCE(updated_at, created_at), completed_at
FROM dblink('dbname=lifeos_prod', '
    SELECT id, domain_id, project_id, parent_id, title, description,
        priority, status, due_date, deadline, recurrence, tags, context,
        is_custom_context, created_at, updated_at, completed_at
    FROM tasks
') AS r0(
    id UUID, domain_id UUID, project_id UUID, parent_id UUID,
    title TEXT, description TEXT, priority INTEGER, status TEXT,
    due_date DATE, deadline TIMESTAMPTZ, recurrence TEXT, tags TEXT[],
    context TEXT, is_custom_context BOOLEAN,
    created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ, completed_at TIMESTAMPTZ
);

-- =============================================================================
-- 5. NOTES
-- R0: id, domain_id, project_id, task_id, title, body, tags,
--     created_at, updated_at, content_format (default 'markdown')
-- R1: + folder_id, meeting_id, is_meeting_note, sort_order,
--       is_deleted, deleted_at, search_vector
-- Transform: content_format 'markdown' -> 'rich'
-- NOTE: R0 task_id dropped (no equivalent in R1 notes).
-- =============================================================================

INSERT INTO notes (id, domain_id, project_id, title, body, content_format, tags,
    is_meeting_note, sort_order, is_deleted, created_at, updated_at)
SELECT id, domain_id, project_id,
    CASE WHEN title IS NULL OR title = '' THEN 'Untitled Note' ELSE title END,
    body,
    CASE WHEN content_format = 'markdown' THEN 'rich' ELSE COALESCE(content_format, 'rich') END,
    tags, false,
    (ROW_NUMBER() OVER (ORDER BY created_at))::INTEGER * 10,
    false, created_at, COALESCE(updated_at, created_at)
FROM dblink('dbname=lifeos_prod', '
    SELECT id, domain_id, project_id, title, body, content_format, tags,
        created_at, updated_at
    FROM notes
') AS r0(
    id UUID, domain_id UUID, project_id UUID, title TEXT, body TEXT,
    content_format TEXT, tags TEXT[],
    created_at TIMESTAMPTZ, updated_at TIMESTAMPTZ
);

-- =============================================================================
-- 6. LINKS
-- R0: id, domain_id, project_id, task_id, label, url, description, created_at
-- R1: + area_id, tags, sort_order, is_deleted, deleted_at, updated_at, search_vector
-- NOTE: R0 task_id dropped (no equivalent in R1 links).
-- =============================================================================

INSERT INTO links (id, domain_id, project_id, label, url, description,
    sort_order, is_deleted, created_at, updated_at)
SELECT id, domain_id, project_id, label, url, description,
    (ROW_NUMBER() OVER (ORDER BY created_at))::INTEGER * 10,
    false, created_at, created_at
FROM dblink('dbname=lifeos_prod', '
    SELECT id, domain_id, project_id, label, url, description, created_at
    FROM links
') AS r0(
    id UUID, domain_id UUID, project_id UUID,
    label TEXT, url TEXT, description TEXT, created_at TIMESTAMPTZ
);

-- =============================================================================
-- 7. DAILY FOCUS
-- R0: id, focus_date, task_id, slot, completed, note, created_at
-- R1: + sort_order, is_deleted, deleted_at
-- =============================================================================

INSERT INTO daily_focus (id, focus_date, task_id, slot, completed, note,
    sort_order, is_deleted, created_at)
SELECT id, focus_date, task_id, slot, COALESCE(completed, false), note,
    COALESCE(slot, (ROW_NUMBER() OVER (PARTITION BY focus_date ORDER BY created_at))::INTEGER) * 10,
    false, created_at
FROM dblink('dbname=lifeos_prod', '
    SELECT id, focus_date, task_id, slot, completed, note, created_at
    FROM daily_focus
') AS r0(
    id UUID, focus_date DATE, task_id UUID, slot INTEGER,
    completed BOOLEAN, note TEXT, created_at TIMESTAMPTZ
);

-- =============================================================================
-- 8. CAPTURE
-- R0: id, raw_text, processed, task_id, created_at
-- R1: + converted_to_type, converted_to_id, area_id, project_id, list_id,
--       import_batch_id, sort_order, is_deleted, deleted_at
-- Map: R0 task_id -> R1 converted_to_type='task', converted_to_id=task_id
-- =============================================================================

INSERT INTO capture (id, raw_text, processed, converted_to_type, converted_to_id,
    sort_order, is_deleted, created_at)
SELECT id, raw_text, COALESCE(processed, false),
    CASE WHEN task_id IS NOT NULL THEN 'task' ELSE NULL END,
    task_id,
    (ROW_NUMBER() OVER (ORDER BY created_at))::INTEGER * 10,
    false, created_at
FROM dblink('dbname=lifeos_prod', '
    SELECT id, raw_text, processed, task_id, created_at FROM capture
') AS r0(
    id UUID, raw_text TEXT, processed BOOLEAN, task_id UUID, created_at TIMESTAMPTZ
);

-- =============================================================================
-- 9. CONTEXT TYPES
-- R0: id (SERIAL), name, description, is_system
-- R1: id (SERIAL), value, label, description, is_system, sort_order, is_deleted
-- Map: R0.name -> R1.value, generate label from name via INITCAP
-- =============================================================================

DELETE FROM context_types;

INSERT INTO context_types (id, value, label, description, is_system, sort_order, is_deleted)
SELECT id, name,
    INITCAP(REPLACE(name, '_', ' ')),
    description, COALESCE(is_system, true),
    id * 10,
    false
FROM dblink('dbname=lifeos_prod', '
    SELECT id, name, description, is_system FROM context_types
') AS r0(id INTEGER, name TEXT, description TEXT, is_system BOOLEAN);

SELECT setval('context_types_id_seq', GREATEST((SELECT MAX(id) FROM context_types), 1));

-- =============================================================================
-- VERIFICATION
-- =============================================================================

DO $$
DECLARE
    r0_domains      INTEGER;
    r0_areas        INTEGER;
    r0_projects     INTEGER;
    r0_tasks        INTEGER;
    r0_notes        INTEGER;
    r0_links        INTEGER;
    r0_daily_focus  INTEGER;
    r0_capture      INTEGER;
    r0_context      INTEGER;
    r1_domains      INTEGER;
    r1_areas        INTEGER;
    r1_projects     INTEGER;
    r1_tasks        INTEGER;
    r1_notes        INTEGER;
    r1_links        INTEGER;
    r1_daily_focus  INTEGER;
    r1_capture      INTEGER;
    r1_context      INTEGER;
BEGIN
    SELECT count INTO r0_domains FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM domains') AS t(count INTEGER);
    SELECT count INTO r0_areas FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM areas') AS t(count INTEGER);
    SELECT count INTO r0_projects FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM projects') AS t(count INTEGER);
    SELECT count INTO r0_tasks FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM tasks') AS t(count INTEGER);
    SELECT count INTO r0_notes FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM notes') AS t(count INTEGER);
    SELECT count INTO r0_links FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM links') AS t(count INTEGER);
    SELECT count INTO r0_daily_focus FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM daily_focus') AS t(count INTEGER);
    SELECT count INTO r0_capture FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM capture') AS t(count INTEGER);
    SELECT count INTO r0_context FROM dblink('dbname=lifeos_prod', 'SELECT count(*) FROM context_types') AS t(count INTEGER);

    SELECT count(*) INTO r1_domains FROM domains;
    SELECT count(*) INTO r1_areas FROM areas;
    SELECT count(*) INTO r1_projects FROM projects;
    SELECT count(*) INTO r1_tasks FROM tasks;
    SELECT count(*) INTO r1_notes FROM notes;
    SELECT count(*) INTO r1_links FROM links;
    SELECT count(*) INTO r1_daily_focus FROM daily_focus;
    SELECT count(*) INTO r1_capture FROM capture;
    SELECT count(*) INTO r1_context FROM context_types;

    RAISE NOTICE '=== MIGRATION VERIFICATION ===';
    RAISE NOTICE 'domains:      R0=% R1=% %', r0_domains, r1_domains, CASE WHEN r0_domains = r1_domains THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'areas:        R0=% R1=% %', r0_areas, r1_areas, CASE WHEN r0_areas = r1_areas THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'projects:     R0=% R1=% %', r0_projects, r1_projects, CASE WHEN r0_projects = r1_projects THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'tasks:        R0=% R1=% %', r0_tasks, r1_tasks, CASE WHEN r0_tasks = r1_tasks THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'notes:        R0=% R1=% %', r0_notes, r1_notes, CASE WHEN r0_notes = r1_notes THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'links:        R0=% R1=% %', r0_links, r1_links, CASE WHEN r0_links = r1_links THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'daily_focus:  R0=% R1=% %', r0_daily_focus, r1_daily_focus, CASE WHEN r0_daily_focus = r1_daily_focus THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'capture:      R0=% R1=% %', r0_capture, r1_capture, CASE WHEN r0_capture = r1_capture THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE 'context_types:R0=% R1=% %', r0_context, r1_context, CASE WHEN r0_context = r1_context THEN 'OK' ELSE 'MISMATCH' END;
    RAISE NOTICE '=== END VERIFICATION ===';
END $$;
