use rusqlite::Connection;

fn hash(n: u32) -> u32 {
    let x = n.wrapping_mul(2654435761);
    let y = (x ^ (x >> 16)).wrapping_mul(2246822519);
    y ^ (y >> 13)
}

fn offset_to_ymd(offset: u32) -> (u32, u32, u32) {
    static MONTHS: [(u32, u32, u32); 12] = [
        (2025, 3, 31),
        (2025, 4, 30),
        (2025, 5, 31),
        (2025, 6, 30),
        (2025, 7, 31),
        (2025, 8, 31),
        (2025, 9, 30),
        (2025, 10, 31),
        (2025, 11, 30),
        (2025, 12, 31),
        (2026, 1, 31),
        (2026, 2, 28),
    ];
    let mut rem = offset;
    for &(y, m, d) in &MONTHS {
        if rem < d {
            return (y, m, rem + 1);
        }
        rem -= d;
    }
    (2026, 2, 28)
}

struct ProjPeriod {
    project_id: i64,
    task_ids: &'static [i64],
    desc_pool: usize,
    start_day: u32,
    end_day: u32,
    billable: i64,
}

static PROJ_PERIODS: &[ProjPeriod] = &[
    ProjPeriod { project_id: 1, task_ids: &[1, 2, 3, 4], desc_pool: 0, start_day: 2, end_day: 75, billable: 1 },
    ProjPeriod { project_id: 2, task_ids: &[5, 6, 7, 8], desc_pool: 1, start_day: 2, end_day: 155, billable: 1 },
    ProjPeriod { project_id: 3, task_ids: &[9, 10, 11, 12], desc_pool: 1, start_day: 33, end_day: 122, billable: 1 },
    ProjPeriod { project_id: 4, task_ids: &[13, 14, 15, 16], desc_pool: 0, start_day: 63, end_day: 183, billable: 1 },
    ProjPeriod { project_id: 5, task_ids: &[17, 18], desc_pool: 7, start_day: 2, end_day: 356, billable: 0 },
    ProjPeriod { project_id: 6, task_ids: &[19, 20, 21], desc_pool: 3, start_day: 93, end_day: 155, billable: 1 },
    ProjPeriod { project_id: 7, task_ids: &[22, 23, 24, 25], desc_pool: 5, start_day: 122, end_day: 183, billable: 1 },
    ProjPeriod { project_id: 8, task_ids: &[26, 27, 28, 29], desc_pool: 0, start_day: 155, end_day: 214, billable: 1 },
    ProjPeriod { project_id: 9, task_ids: &[30, 31, 32, 33], desc_pool: 4, start_day: 184, end_day: 244, billable: 1 },
    ProjPeriod { project_id: 10, task_ids: &[34, 35, 36], desc_pool: 1, start_day: 214, end_day: 244, billable: 1 },
    ProjPeriod { project_id: 11, task_ids: &[37, 38, 39, 40], desc_pool: 5, start_day: 214, end_day: 275, billable: 1 },
    ProjPeriod { project_id: 12, task_ids: &[41, 42, 43], desc_pool: 3, start_day: 245, end_day: 336, billable: 1 },
    ProjPeriod { project_id: 13, task_ids: &[44, 45, 46, 47], desc_pool: 1, start_day: 275, end_day: 356, billable: 1 },
    ProjPeriod { project_id: 14, task_ids: &[48, 49, 50], desc_pool: 1, start_day: 306, end_day: 356, billable: 1 },
    ProjPeriod { project_id: 15, task_ids: &[51, 52], desc_pool: 0, start_day: 306, end_day: 336, billable: 1 },
    ProjPeriod { project_id: 16, task_ids: &[53, 54, 55], desc_pool: 1, start_day: 306, end_day: 356, billable: 1 },
    ProjPeriod { project_id: 17, task_ids: &[56, 57, 58], desc_pool: 1, start_day: 93, end_day: 356, billable: 1 },
    ProjPeriod { project_id: 18, task_ids: &[59, 60], desc_pool: 7, start_day: 214, end_day: 244, billable: 0 },
];

static DESC_POOLS: &[&[&str]] = &[
    // 0: Logo/brand
    &[
        "Concept sketches - exploring directions",
        "Color palette tests on paper",
        "Wordmark spacing and kerning",
        "Symbol refinement - tightening curves",
        "Client presentation deck",
        "Applying revision notes from call",
        "Final vector cleanup and export",
        "Brand guidelines page layout",
        "Moodboard assembly",
        "Scanning hand-drawn letterforms",
    ],
    // 1: Illustration
    &[
        "Thumbnail compositions",
        "Reference gathering and mood board",
        "Rough pencil sketches",
        "Inking line art",
        "Flat color blocking",
        "Rendering pass - light and shadow",
        "Background and texture work",
        "Final cleanup and detail pass",
        "Scanning and color correction",
        "Exploring alternate compositions",
        "Detail work on foreground elements",
        "Adding halftone textures",
    ],
    // 2: Typography/layout
    &[
        "Typography pairing tests",
        "Page layout drafts",
        "Grid and margin adjustments",
        "Hierarchy and scale refinement",
        "Print proof review",
        "Spread layout and flow",
    ],
    // 3: Web/digital
    &[
        "Wireframe sketches on paper",
        "Homepage hero illustration",
        "Responsive layout mockups",
        "Icon set - first batch",
        "Custom divider illustrations",
        "Gallery page layout",
        "Color theme adjustments for screen",
        "Asset export for dev handoff",
    ],
    // 4: Packaging
    &[
        "Die-cut template measurements",
        "Repeating pattern tile design",
        "Label artwork - front panel",
        "Box mockup rendering",
        "Press-ready PDF export",
        "Color proofing adjustments",
        "Tissue paper pattern",
        "Sticker sheet layout",
    ],
    // 5: Book cover
    &[
        "Reading manuscript excerpts for feel",
        "Cover thumbnail sketches",
        "Main illustration - rough draft",
        "Color composition study",
        "Title lettering and spine layout",
        "Full cover rendering",
        "Back cover synopsis layout",
        "Author photo placement and bio",
    ],
    // 6: Meeting/admin
    &[
        "Client call - project kickoff",
        "Reviewing feedback document",
        "Scope and timeline email",
        "Invoice prep and send",
        "File organization and archiving",
    ],
    // 7: Personal
    &[
        "Selecting portfolio pieces",
        "Writing case study notes",
        "Photographing finished prints",
        "Updating website gallery",
        "Sketching for fun",
        "Ink drawing - daily prompt",
        "Scanning and posting work",
        "Reorganizing reference library",
    ],
];

pub fn seed(conn: &Connection) -> Result<(), String> {
    let e = |err: rusqlite::Error| err.to_string();

    conn.execute_batch(
        "PRAGMA foreign_keys = OFF;
         DELETE FROM entry_tags;
         DELETE FROM invoice_payments;
         DELETE FROM invoice_items;
         DELETE FROM recurring_invoices;
         DELETE FROM invoices;
         DELETE FROM favorites;
         DELETE FROM recurring_entries;
         DELETE FROM entry_templates;
         DELETE FROM timesheet_rows;
         DELETE FROM timesheet_locks;
         DELETE FROM timeline_events;
         DELETE FROM expenses;
         DELETE FROM tracked_apps;
         DELETE FROM time_entries;
         DELETE FROM tasks;
         DELETE FROM projects;
         DELETE FROM clients;
         DELETE FROM tags;
         DELETE FROM calendar_events;
         DELETE FROM calendar_sources;
         DELETE FROM sqlite_sequence;
         PRAGMA foreign_keys = ON;",
    )
    .map_err(e)?;

    // ==========================================
    // CLIENTS
    // ==========================================
    conn.execute_batch(
        "INSERT INTO clients (id, name, email, company, phone, payment_terms, notes) VALUES
         (1, 'Anna Kowalski', 'anna@moonlightbakery.com', 'Moonlight Bakery', '555-0142', 'net_30', 'Longtime client. Loves warm earth tones and hand-drawn feel.'),
         (2, 'James Okonkwo', 'james@riverandstone.com', 'River & Stone Pottery', '555-0238', 'net_15', 'Prefers email. Needs high-res for print catalog.'),
         (3, 'Rosa Delgado', 'rosa@velvetsparrow.com', 'The Velvet Sparrow', '555-0319', 'net_30', 'Band manager. Quick feedback, clear direction.'),
         (4, 'Tom Brennan', 'tom@fernandwillow.com', 'Fern & Willow Cafe', '555-0421', 'net_30', 'Very responsive. The cafe on Elm St has great coffee.'),
         (5, 'Marcus Chen', 'marcus@marcuschen.com', NULL, '555-0517', 'due_on_receipt', 'Photographer. Good referral source.'),
         (6, 'Diane Huang', 'diane@wildfieldpress.com', 'Wildfield Press', '555-0634', 'net_45', 'Publisher - steady ongoing work. Pays reliably.'),
         (7, 'Kai Nishimura', 'kai@sableandco.com', 'Sable & Co Tattoo', '555-0728', 'net_15', 'Expects fast turnaround. Loves bold linework.');",
    )
    .map_err(e)?;

    // ==========================================
    // PROJECTS
    // ==========================================
    conn.execute_batch(
        "INSERT INTO projects (id, client_id, name, hourly_rate, color, archived, budget_hours, notes) VALUES
         (1,  1, 'Moonlight Logo Redesign',      65, '#F59E0B', 1, 50,  'Modernizing the logo. Keep the crescent moon motif.'),
         (2,  2, 'Product Catalog',               70, '#8B5CF6', 1, 130, '48-page catalog for spring/summer pottery collection.'),
         (3,  3, 'Album Cover - Quiet Hours',     75, '#EF4444', 1, 65,  'Debut album. Dreamy watercolor feel, night sky theme.'),
         (4,  4, 'Fern & Willow Rebrand',         70, '#10B981', 1, 110, 'Full rebrand - logo, menu boards, signage, socials.'),
         (5,  NULL, 'Portfolio Update',             0, '#6B7280', 0, NULL, 'Ongoing portfolio maintenance and case studies.'),
         (6,  5, 'Portfolio Website',              60, '#3B82F6', 1, 55,  'Custom illustrations for photography portfolio.'),
         (7,  6, 'Tide Pool Dreams - Cover',       75, '#06B6D4', 1, 60,  'Middle-grade novel cover. Lush underwater scene.'),
         (8,  7, 'Sable & Co Brand Kit',           80, '#A855F7', 1, 55,  'Full identity - logo, cards, signage, flash sheet.'),
         (9,  1, 'Seasonal Packaging',             60, '#EC4899', 1, 70,  'Holiday gift box designs and labels.'),
         (10, 3, 'Tour Poster - West Coast',       60, '#DC2626', 1, 35,  'Screenprint poster for 12-city tour.'),
         (11, 6, 'Moth & Lantern - Cover',         75, '#0EA5E9', 1, 60,  'YA fantasy novel cover. Moths, lantern light, forest.'),
         (12, 2, 'Website Illustrations',          65, '#6366F1', 0, 85,  'Custom spot illustrations for new e-commerce site.'),
         (13, 4, 'Mural Design',                   65, '#34D399', 0, 75,  'Interior mural - botanical garden theme, 8ft x 12ft.'),
         (14, 1, 'Menu Illustrations',             55, '#F97316', 0, 45,  'Hand-drawn food illos for seasonal menu refresh.'),
         (15, 5, 'Business Cards',                 50, '#60A5FA', 1, 18,  'Custom illustrated business card with foil stamp.'),
         (16, 3, 'Merch Designs',                  55, '#F43F5E', 0, 40,  'T-shirt, sticker, and tote bag art for online store.'),
         (17, 6, 'Monthly Spot Illustrations',     50, '#14B8A6', 0, 100, 'Recurring spot illos for chapter headers in books.'),
         (18, NULL, 'Inktober 2025',                0, '#1F2937', 1, NULL, 'Personal daily ink drawing challenge.');",
    )
    .map_err(e)?;

    // ==========================================
    // TASKS (60 tasks across 18 projects)
    // ==========================================
    conn.execute_batch(
        "INSERT INTO tasks (id, project_id, name, estimated_hours) VALUES
         (1,  1, 'Research',           8),
         (2,  1, 'Sketching',          15),
         (3,  1, 'Refinement',         15),
         (4,  1, 'Final Delivery',     10),
         (5,  2, 'Photography Layout', 30),
         (6,  2, 'Illustration',       50),
         (7,  2, 'Typography',         25),
         (8,  2, 'Print Prep',         20),
         (9,  3, 'Concept Art',        15),
         (10, 3, 'Main Illustration',  25),
         (11, 3, 'Lettering',          12),
         (12, 3, 'File Prep',          8),
         (13, 4, 'Brand Strategy',     15),
         (14, 4, 'Logo Design',        35),
         (15, 4, 'Collateral',         35),
         (16, 4, 'Signage',            20),
         (17, 5, 'Curation',           NULL),
         (18, 5, 'Photography',        NULL),
         (19, 6, 'Wireframes',         12),
         (20, 6, 'Visual Design',      25),
         (21, 6, 'Asset Creation',     15),
         (22, 7, 'Reading',            8),
         (23, 7, 'Sketches',           15),
         (24, 7, 'Cover Art',          25),
         (25, 7, 'Layout',             10),
         (26, 8, 'Research',           10),
         (27, 8, 'Concepts',           15),
         (28, 8, 'Refinement',         18),
         (29, 8, 'Brand Kit',          12),
         (30, 9, 'Template Setup',     10),
         (31, 9, 'Pattern Design',     20),
         (32, 9, 'Label Art',          25),
         (33, 9, 'Press Files',        12),
         (34, 10, 'Layout',            10),
         (35, 10, 'Illustration',      18),
         (36, 10, 'Print Prep',        5),
         (37, 11, 'Reading',           8),
         (38, 11, 'Sketches',          15),
         (39, 11, 'Cover Art',         25),
         (40, 11, 'Layout',            10),
         (41, 12, 'Page Illustrations', 30),
         (42, 12, 'Icon Set',          25),
         (43, 12, 'Banner Art',        20),
         (44, 13, 'Concept',           12),
         (45, 13, 'Scale Drawing',     20),
         (46, 13, 'Color Studies',     18),
         (47, 13, 'Detail Work',       22),
         (48, 14, 'Food Illustrations', 20),
         (49, 14, 'Layout',            12),
         (50, 14, 'Spot Art',          10),
         (51, 15, 'Design',            12),
         (52, 15, 'Print Prep',        5),
         (53, 16, 'T-shirt Art',       15),
         (54, 16, 'Sticker Designs',   12),
         (55, 16, 'Tote Bag Art',      10),
         (56, 17, 'Sketching',         35),
         (57, 17, 'Inking',            35),
         (58, 17, 'Coloring',          25),
         (59, 18, 'Daily Prompts',     NULL),
         (60, 18, 'Scanning',          NULL);",
    )
    .map_err(e)?;

    // ==========================================
    // TAGS
    // ==========================================
    conn.execute_batch(
        "INSERT INTO tags (id, name, color) VALUES
         (1, 'rush',     '#EF4444'),
         (2, 'revision', '#F59E0B'),
         (3, 'pro-bono', '#10B981'),
         (4, 'personal', '#6B7280'),
         (5, 'concept',  '#8B5CF6'),
         (6, 'final',    '#3B82F6'),
         (7, 'meeting',  '#EC4899'),
         (8, 'admin',    '#6366F1');",
    )
    .map_err(e)?;

    // ==========================================
    // TIME ENTRIES (generated)
    // ==========================================
    let mut stmt = conn
        .prepare(
            "INSERT INTO time_entries (project_id, task_id, description, start_time, end_time, duration, billable)
             VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
        )
        .map_err(e)?;

    let session_starts: [(u32, u32); 4] = [(9, 0), (11, 0), (13, 30), (16, 0)];
    let session_maxmins: [u32; 4] = [120, 150, 150, 120];

    let mut entry_count: i64 = 0;

    for day_offset in 0u32..357 {
        let dow = (6 + day_offset) % 7;
        if dow == 0 || dow == 6 {
            // Weekend: only Inktober gets weekend work
            if day_offset >= 214 && day_offset <= 244 {
                let h = hash(day_offset);
                if h % 3 == 0 {
                    let (y, m, d) = offset_to_ymd(day_offset);
                    let date = format!("{:04}-{:02}-{:02}", y, m, d);
                    let di = (h / 7) as usize % DESC_POOLS[7].len();
                    let ti = if h % 2 == 0 { 59i64 } else { 60 };
                    let dur_mins = 30 + (h % 60);
                    let start = format!("{}T10:{:02}:00", date, h % 45);
                    let dur_secs = (dur_mins * 60) as i64;
                    let end_mins = 10 * 60 + (h % 45) + dur_mins;
                    let end = format!("{}T{:02}:{:02}:00", date, end_mins / 60, end_mins % 60);
                    stmt.execute(rusqlite::params![18i64, ti, DESC_POOLS[7][di], start, end, dur_secs, 0i64]).map_err(e)?;
                    entry_count += 1;
                }
            }
            continue;
        }

        let h = hash(day_offset);
        // Skip ~5% of weekdays (sick/vacation)
        if h % 20 == 0 {
            continue;
        }

        let (y, m, d) = offset_to_ymd(day_offset);
        let date = format!("{:04}-{:02}-{:02}", y, m, d);

        // Collect active projects
        let active: Vec<&ProjPeriod> = PROJ_PERIODS
            .iter()
            .filter(|p| day_offset >= p.start_day && day_offset <= p.end_day)
            .filter(|p| {
                // Personal/portfolio only shows up ~15% of days
                if p.project_id == 5 {
                    return hash(day_offset.wrapping_mul(5)) % 7 == 0;
                }
                true
            })
            .collect();

        if active.is_empty() {
            continue;
        }

        let n_sessions = 2 + (h % 2) as usize; // 2-3 sessions
        let n_sessions = n_sessions.min(active.len().max(2));

        for s in 0..n_sessions {
            if s >= 4 {
                break;
            }
            let sh = hash(day_offset * 100 + s as u32);
            let proj_idx = (sh as usize) % active.len();
            let proj = active[proj_idx];

            let task_idx = (sh / 3) as usize % proj.task_ids.len();
            let task_id = proj.task_ids[task_idx];
            let pool = DESC_POOLS[proj.desc_pool];
            let desc_idx = (sh / 7) as usize % pool.len();
            let desc = pool[desc_idx];

            let (base_h, base_m) = session_starts[s];
            let max_mins = session_maxmins[s];
            let dur_mins = 45 + sh % (max_mins - 44);
            let start_offset_mins = (sh / 11) % 20;
            let start_h = base_h + (base_m + start_offset_mins) / 60;
            let start_m = (base_m + start_offset_mins) % 60;
            let end_total = start_h * 60 + start_m + dur_mins;
            let end_h = end_total / 60;
            let end_m = end_total % 60;

            if end_h >= 19 {
                continue;
            }

            let start = format!("{}T{:02}:{:02}:00", date, start_h, start_m);
            let end = format!("{}T{:02}:{:02}:00", date, end_h, end_m);
            let dur_secs = (dur_mins * 60) as i64;

            stmt.execute(rusqlite::params![
                proj.project_id,
                task_id,
                desc,
                start,
                end,
                dur_secs,
                proj.billable
            ])
            .map_err(e)?;
            entry_count += 1;
        }

        // Occasional admin/meeting entry (~20% of days)
        if h % 5 == 0 && !active.is_empty() {
            let sh = hash(day_offset * 200);
            let proj = active[0];
            let admin_descs = DESC_POOLS[6];
            let di = (sh / 3) as usize % admin_descs.len();
            let dur_mins = 15 + sh % 30;
            let start = format!("{}T08:{:02}:00", date, 30 + sh % 25);
            let end_total_mins = 8 * 60 + 30 + (sh % 25) + dur_mins;
            let end = format!(
                "{}T{:02}:{:02}:00",
                date,
                end_total_mins / 60,
                end_total_mins % 60
            );
            stmt.execute(rusqlite::params![
                proj.project_id,
                proj.task_ids[0],
                admin_descs[di],
                start,
                end,
                (dur_mins * 60) as i64,
                proj.billable
            ])
            .map_err(e)?;
            entry_count += 1;
        }
    }

    drop(stmt);

    // ==========================================
    // ENTRY TAGS (tag ~15% of entries)
    // ==========================================
    let total_entries = entry_count;
    let tag_assignments: Vec<(i64, i64)> = (1..=total_entries)
        .filter_map(|id| {
            let h = hash(id as u32 * 31);
            if h % 7 != 0 {
                return None;
            }
            let tag = match h % 40 {
                0..=5 => 1,   // rush
                6..=15 => 2,  // revision
                16..=20 => 5, // concept
                21..=28 => 6, // final
                29..=33 => 7, // meeting
                34..=37 => 8, // admin
                _ => 2,       // revision
            };
            Some((id, tag))
        })
        .collect();

    let mut tag_stmt = conn
        .prepare("INSERT OR IGNORE INTO entry_tags (entry_id, tag_id) VALUES (?1, ?2)")
        .map_err(e)?;
    for (eid, tid) in &tag_assignments {
        tag_stmt.execute(rusqlite::params![eid, tid]).map_err(e)?;
    }
    drop(tag_stmt);

    // ==========================================
    // EXPENSES
    // ==========================================
    conn.execute_batch(
        "INSERT INTO expenses (project_id, client_id, category, description, amount, date, invoiced) VALUES
         -- Software subscriptions (monthly)
         (5,  NULL, 'software', 'Clip Studio Paint Pro - annual',        49.99, '2025-03-15', 0),
         (5,  NULL, 'software', 'Affinity Designer 2 license',           69.99, '2025-04-02', 0),
         (5,  NULL, 'software', 'Dropbox Plus - annual renewal',        119.88, '2025-06-01', 0),
         (5,  NULL, 'software', 'Squarespace portfolio site - annual',  192.00, '2025-07-15', 0),
         (17, 6,    'software', 'Font license - Recoleta family',        45.00, '2025-08-20', 1),

         -- Art supplies
         (1,  1,  'supplies', 'Copic markers (12 pack, warm grays)',      89.99, '2025-03-08', 0),
         (3,  3,  'supplies', 'Winsor & Newton watercolor set',          124.50, '2025-04-10', 0),
         (2,  2,  'supplies', 'A3 hot press watercolor paper (50 sheets)', 42.00, '2025-05-05', 0),
         (4,  4,  'supplies', 'Posca paint markers (8 pack)',             34.99, '2025-06-18', 0),
         (18, NULL,'supplies', 'India ink - Sumi (3 bottles)',            27.50, '2025-10-01', 0),
         (18, NULL,'supplies', 'Micron pen set (8 widths)',               22.99, '2025-10-03', 0),
         (13, 4,  'supplies', 'Acrylic paint (mural - bulk order)',      187.00, '2025-12-20', 0),
         (14, 1,  'supplies', 'Brush pen set for menu illos',             18.50, '2026-01-12', 0),

         -- Printing
         (2,  2,  'printing', 'Test prints - catalog spreads',            85.00, '2025-07-22', 1),
         (9,  1,  'printing', 'Packaging prototypes (6 units)',          120.00, '2025-10-15', 1),
         (10, 3,  'printing', 'Poster screenprint run (50 copies)',      275.00, '2025-11-01', 1),
         (15, 5,  'printing', 'Business card print run (250)',            65.00, '2026-01-28', 1),

         -- Reference materials
         (5,  NULL, 'other', 'Illustration annual 2025',                  38.00, '2025-04-22', 0),
         (5,  NULL, 'other', 'Color and Light by James Gurney',           28.50, '2025-05-30', 0),
         (7,  6,   'other', 'Marine biology reference photos (stock)',    29.00, '2025-07-10', 1),

         -- Travel
         (4,  4,  'travel', 'Bus pass - client site visits (monthly)',    45.00, '2025-06-01', 0),
         (4,  4,  'travel', 'Bus pass - client site visits (monthly)',    45.00, '2025-07-01', 0),
         (8,  7,  'travel', 'Transit to tattoo parlor for measurements',  8.50, '2025-08-12', 0),
         (13, 4,  'travel', 'Transit to cafe for mural measurements',     8.50, '2025-12-15', 0),
         (13, 4,  'travel', 'Transit to cafe - mural install day',        8.50, '2026-02-10', 0),

         -- Equipment
         (5,  NULL, 'equipment', 'Tablet screen protector replacement',   24.99, '2025-09-05', 0),
         (5,  NULL, 'equipment', 'Desk lamp (daylight bulb)',             45.00, '2025-11-20', 0);",
    )
    .map_err(e)?;

    // ==========================================
    // INVOICES
    // ==========================================
    conn.execute_batch(
        "INSERT INTO invoices (id, client_id, invoice_number, date, due_date, subtotal, tax_rate, tax_amount, discount, total, notes, status) VALUES
         (1,  1, 'INV-2025-001', '2025-05-28', '2025-06-27', 3120.00, 0, 0, 0, 3120.00, 'Logo redesign - concept through final delivery', 'paid'),
         (2,  2, 'INV-2025-002', '2025-06-15', '2025-06-30', 4550.00, 0, 0, 0, 4550.00, 'Product catalog - first milestone (layout and illustrations)', 'paid'),
         (3,  3, 'INV-2025-003', '2025-06-30', '2025-07-30', 4500.00, 0, 0, 0, 4500.00, 'Album cover art - Quiet Hours', 'paid'),
         (4,  4, 'INV-2025-004', '2025-07-31', '2025-08-30', 3850.00, 0, 0, 0, 3850.00, 'Rebrand milestone 1 - logo and primary collateral', 'paid'),
         (5,  2, 'INV-2025-005', '2025-08-15', '2025-08-30', 3850.00, 0, 0, 0, 3850.00, 'Product catalog - final milestone (print prep)', 'paid'),
         (6,  5, 'INV-2025-006', '2025-08-20', '2025-08-20', 3000.00, 0, 0, 0, 3000.00, 'Portfolio website illustrations', 'paid'),
         (7,  6, 'INV-2025-007', '2025-09-10', '2025-10-25', 4125.00, 0, 0, 0, 4125.00, 'Tide Pool Dreams - cover art', 'paid'),
         (8,  4, 'INV-2025-008', '2025-09-30', '2025-10-30', 3500.00, 0, 0, 0, 3500.00, 'Rebrand milestone 2 - signage and social templates', 'paid'),
         (9,  7, 'INV-2025-009', '2025-10-20', '2025-11-04', 4160.00, 0, 0, 0, 4160.00, 'Sable & Co - full brand kit', 'paid'),
         (10, 6, 'INV-2025-010', '2025-09-30', '2025-11-14', 2250.00, 0, 0, 0, 2250.00, 'Monthly spot illustrations - Q3 (Jul-Sep)', 'overdue'),
         (11, 1, 'INV-2025-011', '2025-11-25', '2025-12-25', 3780.00, 0, 0, 0, 3780.00, 'Seasonal packaging - holiday gift line', 'paid'),
         (12, 3, 'INV-2025-012', '2025-11-20', '2025-12-20', 1860.00, 0, 0, 0, 1860.00, 'Tour poster - West Coast (design + print mgmt)', 'paid'),
         (13, 6, 'INV-2025-013', '2025-12-20', '2026-02-03', 4275.00, 0, 0, 0, 4275.00, 'Moth & Lantern - cover art', 'sent'),
         (14, 6, 'INV-2025-014', '2025-12-31', '2026-02-14', 2500.00, 0, 0, 0, 2500.00, 'Monthly spot illustrations - Q4 (Oct-Dec)', 'sent'),
         (15, 2, 'INV-2026-001', '2026-01-31', '2026-02-14', 4225.00, 0, 0, 0, 4225.00, 'Website illustrations - first half', 'sent'),
         (16, 4, 'INV-2026-002', '2026-02-15', '2026-03-17', 2600.00, 0, 0, 0, 2600.00, 'Mural design - concept and scale drawing', 'draft'),
         (17, 1, 'INV-2026-003', '2026-02-20', '2026-03-22', 1100.00, 0, 0, 0, 1100.00, 'Menu illustrations - in progress', 'draft'),
         (18, 5, 'INV-2026-004', '2026-01-25', '2026-01-25',  750.00, 0, 0, 0,  750.00, 'Business card design and print coordination', 'paid');",
    )
    .map_err(e)?;

    // ==========================================
    // INVOICE ITEMS
    // ==========================================
    conn.execute_batch(
        "INSERT INTO invoice_items (invoice_id, description, quantity, rate, amount) VALUES
         (1,  'Logo redesign - research and concepts',       12, 65, 780),
         (1,  'Logo refinement and final artwork',           24, 65, 1560),
         (1,  'Brand guidelines document',                   12, 65, 780),
         (2,  'Catalog layout - 24 spreads',                 30, 70, 2100),
         (2,  'Product illustrations',                       35, 70, 2450),
         (3,  'Album cover art - concept through final',     48, 75, 3600),
         (3,  'File preparation and print variants',         12, 75, 900),
         (4,  'Brand strategy and logo design',              35, 70, 2450),
         (4,  'Collateral design (menu, cards, social)',     20, 70, 1400),
         (5,  'Catalog - typography and print preparation',  25, 70, 1750),
         (5,  'Final revisions and press files',             30, 70, 2100),
         (6,  'Website illustrations and icons',             50, 60, 3000),
         (7,  'Cover illustration - concept to final',       45, 75, 3375),
         (7,  'Layout, spine, and back cover',               10, 75, 750),
         (8,  'Signage designs (3 pieces)',                  25, 70, 1750),
         (8,  'Social media template set',                   25, 70, 1750),
         (9,  'Logo and brand identity development',         32, 80, 2560),
         (9,  'Brand kit - cards, signage, flash style',     20, 80, 1600),
         (10, 'Spot illustrations - July',                   15, 50, 750),
         (10, 'Spot illustrations - August',                 15, 50, 750),
         (10, 'Spot illustrations - September',              15, 50, 750),
         (11, 'Packaging design - 4 box sizes',             40, 60, 2400),
         (11, 'Label art and tissue paper pattern',         23, 60, 1380),
         (12, 'Poster illustration and layout',             24, 60, 1440),
         (12, 'Print management and color proofing',         7, 60, 420),
         (13, 'Cover illustration - Moth & Lantern',        45, 75, 3375),
         (13, 'Layout and final files',                     12, 75, 900),
         (14, 'Spot illustrations - October',               18, 50, 900),
         (14, 'Spot illustrations - November',              16, 50, 800),
         (14, 'Spot illustrations - December',              16, 50, 800),
         (15, 'Page illustrations - 12 pieces',             40, 65, 2600),
         (15, 'Icon set - first batch (20 icons)',          25, 65, 1625),
         (16, 'Mural concept sketches',                     15, 65, 975),
         (16, 'Scale drawing and color studies',            25, 65, 1625),
         (17, 'Food illustrations (8 of 15)',               20, 55, 1100),
         (18, 'Business card design - illustration + layout', 12, 50, 600),
         (18, 'Print coordination',                          3, 50, 150);",
    )
    .map_err(e)?;

    // ==========================================
    // INVOICE PAYMENTS
    // ==========================================
    conn.execute_batch(
        "INSERT INTO invoice_payments (invoice_id, amount, date, method, notes) VALUES
         (1,  3120.00, '2025-06-20', 'bank_transfer', 'Paid in full'),
         (2,  4550.00, '2025-06-28', 'bank_transfer', NULL),
         (3,  4500.00, '2025-07-25', 'bank_transfer', NULL),
         (4,  3850.00, '2025-08-28', 'bank_transfer', NULL),
         (5,  3850.00, '2025-08-29', 'bank_transfer', NULL),
         (6,  3000.00, '2025-08-20', 'bank_transfer', 'Paid same day'),
         (7,  4125.00, '2025-10-22', 'bank_transfer', NULL),
         (8,  3500.00, '2025-10-28', 'bank_transfer', NULL),
         (9,  4160.00, '2025-11-02', 'bank_transfer', 'Paid early'),
         (11, 3780.00, '2025-12-18', 'bank_transfer', NULL),
         (12, 1860.00, '2025-12-15', 'bank_transfer', NULL),
         (18,  750.00, '2026-01-25', 'bank_transfer', 'Paid on receipt');",
    )
    .map_err(e)?;

    // ==========================================
    // FAVORITES
    // ==========================================
    conn.execute_batch(
        "INSERT INTO favorites (project_id, task_id, description, sort_order) VALUES
         (13, 44, 'Mural concept work',         0),
         (14, 48, 'Menu food illustrations',     1),
         (17, 56, 'Monthly spot illo',           2),
         (16, 53, 'Merch design session',        3);",
    )
    .map_err(e)?;

    // ==========================================
    // ENTRY TEMPLATES
    // ==========================================
    conn.execute_batch(
        "INSERT INTO entry_templates (name, project_id, task_id, description, duration, billable) VALUES
         ('Quick sketch session',    13, 44, 'Concept sketching',        5400, 1),
         ('Spot illustration',       17, 57, 'Inking spot illustration', 7200, 1),
         ('Portfolio photo session', 5,  18, 'Photographing prints',     3600, 0),
         ('Menu illo',               14, 48, 'Food illustration',        5400, 1);",
    )
    .map_err(e)?;

    // ==========================================
    // TRACKED APPS
    // ==========================================
    conn.execute_batch(
        "INSERT INTO tracked_apps (project_id, exe_name, display_name) VALUES
         (13, 'clip_studio_paint.exe', 'Clip Studio Paint'),
         (14, 'clip_studio_paint.exe', 'Clip Studio Paint'),
         (12, 'affinity_designer.exe', 'Affinity Designer'),
         (16, 'affinity_designer.exe', 'Affinity Designer');",
    )
    .map_err(e)?;

    // ==========================================
    // BUSINESS IDENTITY (for invoice previews)
    // ==========================================
    conn.execute_batch(
        "INSERT OR REPLACE INTO settings (key, value) VALUES
         ('business_name',    'Mika Sato Illustration'),
         ('business_address', '47 Brush & Ink Lane\nPortland, OR 97205'),
         ('business_email',   'hello@mikasato.art'),
         ('business_phone',   '(503) 555-0147'),
         ('hourly_rate',      '95');",
    )
    .map_err(e)?;

    Ok(())
}
