import { PrismaClient, UserRole, EmailTemplateCategory } from '@prisma/client';
import bcrypt from 'bcryptjs';
import * as fs from 'fs';
import * as path from 'path';
import { env } from '../src/config/env';
import { initEncryption, encrypt } from '../src/utils/crypto';

const prisma = new PrismaClient();

async function main() {
  console.log('Seeding database...');

  // Create default super admin from environment variables
  // Skip creation if password is a placeholder (contains "CHANGE_THIS")
  const initialAdminEmail = env.INITIAL_ADMIN_EMAIL;
  const initialAdminPassword = env.INITIAL_ADMIN_PASSWORD;

  let admin: { id: string; email: string } | null = null;

  // Validate password meets policy before proceeding
  if (initialAdminPassword.length < 12 ||
      !/[A-Z]/.test(initialAdminPassword) ||
      !/[a-z]/.test(initialAdminPassword) ||
      !/[0-9]/.test(initialAdminPassword)) {
    console.warn('⚠️  INITIAL_ADMIN_PASSWORD does not meet password policy (12+ chars, uppercase, lowercase, digit)');
    console.warn('⚠️  Skipping admin user creation. Please set a valid password in .env');
  } else if (initialAdminPassword.includes('CHANGE_THIS') || initialAdminPassword.includes('REQUIRED')) {
    console.warn('⚠️  INITIAL_ADMIN_PASSWORD contains placeholder value');
    console.warn('⚠️  Skipping admin user creation. Please set a real password in .env');
  } else {
    const hashedPassword = await bcrypt.hash(initialAdminPassword, 12);

    admin = await prisma.user.upsert({
      where: { email: initialAdminEmail },
      update: {
        password: hashedPassword,
        emailVerified: true,
        status: 'ACTIVE',
      },
      create: {
        email: initialAdminEmail,
        password: hashedPassword,
        name: 'Admin',
        role: UserRole.SUPER_ADMIN,
        roles: JSON.parse(JSON.stringify([UserRole.SUPER_ADMIN])),
        emailVerified: true,
      },
    });

    console.log(`✅ Created/updated admin user: ${admin.email}`);
  }

  // If admin wasn't created (placeholder password), try to find existing admin
  if (!admin) {
    admin = await prisma.user.findFirst({
      where: { role: UserRole.SUPER_ADMIN },
      select: { id: true, email: true },
    });
    if (admin) {
      console.log(`ℹ️  Found existing admin user: ${admin.email}`);
    } else {
      console.error('❌ FATAL: No SUPER_ADMIN user exists and none could be created.');
      console.error('   Fix INITIAL_ADMIN_PASSWORD in .env (12+ chars, uppercase, lowercase, digit)');
      process.exit(2);
    }
  }

  // Create default map settings
  await prisma.mapSettings.upsert({
    where: { id: 'default' },
    update: {},
    create: {
      id: 'default',
      latitude: 53.5461,
      longitude: -113.4938,
      zoom: 11,
      walkSheetTitle: 'Walk Sheet',
      walkSheetSubtitle: '',
      walkSheetFooter: '',
    },
  });

  console.log('Created default map settings');

  // Seed SiteSettings with .env SMTP values (only if no row exists yet)
  const existingSettings = await prisma.siteSettings.findFirst();
  if (!existingSettings) {
    // Initialize encryption so we can encrypt the SMTP password
    const encryptionKey = env.ENCRYPTION_KEY || env.JWT_ACCESS_SECRET;
    initEncryption(encryptionKey);

    const isMailhog = env.EMAIL_TEST_MODE === 'true' || env.SMTP_HOST === 'mailhog-changemaker';

    await prisma.siteSettings.create({
      data: {
        smtpHost: env.SMTP_HOST,
        smtpPort: env.SMTP_PORT,
        smtpUser: env.SMTP_USER,
        smtpPass: env.SMTP_PASS ? encrypt(env.SMTP_PASS) : '',
        smtpFromAddress: env.SMTP_FROM,
        emailFromName: env.SMTP_FROM_NAME,
        smtpActiveProvider: isMailhog ? 'mailhog' : 'production',
        emailTestMode: env.EMAIL_TEST_MODE === 'true',
        testEmailRecipient: env.TEST_EMAIL_RECIPIENT,
        // Feature flags from .env (DB authoritative once admin saves settings)
        enableMediaFeatures: env.ENABLE_MEDIA_FEATURES !== 'false',
        enableChat: env.ENABLE_CHAT === 'true',
        enableMeet: env.ENABLE_MEET === 'true',
        enableSms: env.ENABLE_SMS === 'true',
        enablePayments: env.ENABLE_PAYMENTS === 'true',
        enableSocial: env.ENABLE_SOCIAL === 'true',
        enablePeople: env.ENABLE_PEOPLE === 'true',
        enableAnalytics: env.ENABLE_ANALYTICS === 'true',
        enableEvents: env.GANCIO_SYNC_ENABLED === 'true',
        enableNewsletter: env.LISTMONK_SYNC_ENABLED === 'true',
        navConfig: {
          items: [
            { id: 'home', label: 'Home', path: '/', icon: 'HomeOutlined', enabled: true, order: 0, type: 'builtin', external: true },
            { id: 'campaigns', label: 'Campaigns', path: '/campaigns', icon: 'SendOutlined', enabled: true, order: 1, type: 'builtin', featureFlag: 'enableInfluence' },
            { id: 'map', label: 'Map', path: '/map', icon: 'EnvironmentOutlined', enabled: true, order: 2, type: 'builtin', featureFlag: 'enableMap' },
            { id: 'shifts', label: 'Shifts', path: '/shifts', icon: 'CalendarOutlined', enabled: true, order: 3, type: 'builtin', featureFlag: 'enableMap' },
            { id: 'events', label: 'Events', path: '/events', icon: 'CalendarOutlined', enabled: true, order: 4, type: 'builtin', featureFlag: 'enableEvents', external: true },
            { id: 'gallery', label: 'Gallery', path: '/gallery', icon: 'PlayCircleOutlined', enabled: true, order: 5, type: 'builtin', featureFlag: 'enableMediaFeatures' },
            { id: 'pricing', label: 'Pricing', path: '/pricing', icon: 'DollarOutlined', enabled: true, order: 6, type: 'builtin', featureFlag: 'enablePayments' },
            { id: 'shop', label: 'Shop', path: '/shop', icon: 'ShoppingOutlined', enabled: true, order: 7, type: 'builtin', featureFlag: 'enablePayments' },
            { id: 'donate', label: 'Donate', path: '/donate', icon: 'HeartOutlined', enabled: true, order: 8, type: 'builtin', featureFlag: 'enablePayments' },
            { id: 'landing', label: 'Website', path: '$landing', icon: 'GlobalOutlined', enabled: false, order: 9, type: 'builtin', external: true },
            { id: 'docs', label: 'Docs', path: '$docs', icon: 'BookOutlined', enabled: false, order: 10, type: 'builtin', external: true },
          ],
        },
      },
    });
    console.log('Created SiteSettings with SMTP config + navConfig from .env');
  } else {
    console.log('SiteSettings already exists, skipping SMTP seeding');

    // Seed navConfig if null (existing installations)
    if (!existingSettings.navConfig) {
      const defaultNavConfig = {
        items: [
          { id: 'home', label: 'Home', path: '/', icon: 'HomeOutlined', enabled: true, order: 0, type: 'builtin', external: true },
          { id: 'campaigns', label: 'Campaigns', path: '/campaigns', icon: 'SendOutlined', enabled: true, order: 1, type: 'builtin', featureFlag: 'enableInfluence' },
          { id: 'map', label: 'Map', path: '/map', icon: 'EnvironmentOutlined', enabled: true, order: 2, type: 'builtin', featureFlag: 'enableMap' },
          { id: 'shifts', label: 'Shifts', path: '/shifts', icon: 'CalendarOutlined', enabled: true, order: 3, type: 'builtin', featureFlag: 'enableMap' },
          { id: 'events', label: 'Events', path: '/events', icon: 'CalendarOutlined', enabled: true, order: 4, type: 'builtin', featureFlag: 'enableEvents', external: true },
          { id: 'gallery', label: 'Gallery', path: '/gallery', icon: 'PlayCircleOutlined', enabled: true, order: 5, type: 'builtin', featureFlag: 'enableMediaFeatures' },
          { id: 'pricing', label: 'Pricing', path: '/pricing', icon: 'DollarOutlined', enabled: true, order: 6, type: 'builtin', featureFlag: 'enablePayments' },
          { id: 'shop', label: 'Shop', path: '/shop', icon: 'ShoppingOutlined', enabled: true, order: 7, type: 'builtin', featureFlag: 'enablePayments' },
          { id: 'donate', label: 'Donate', path: '/donate', icon: 'HeartOutlined', enabled: true, order: 8, type: 'builtin', featureFlag: 'enablePayments' },
          { id: 'landing', label: 'Website', path: '$landing', icon: 'GlobalOutlined', enabled: false, order: 9, type: 'builtin', external: true },
          { id: 'docs', label: 'Docs', path: '$docs', icon: 'BookOutlined', enabled: false, order: 10, type: 'builtin', external: true },
        ],
      };
      await prisma.siteSettings.update({
        where: { id: existingSettings.id },
        data: { navConfig: defaultNavConfig },
      });
      console.log('Seeded default navConfig on existing SiteSettings');
    }
  }

  // Create default page blocks for landing page builder
  const defaultBlocks = [
    {
      id: 'default-hero',
      type: 'hero',
      label: 'Hero Section',
      category: 'Headers',
      sortOrder: 1,
      schema: {
        title: { type: 'string', label: 'Title' },
        subtitle: { type: 'string', label: 'Subtitle' },
        backgroundImage: { type: 'string', label: 'Background Image URL' },
        ctaText: { type: 'string', label: 'Button Text' },
        ctaUrl: { type: 'string', label: 'Button URL' },
      },
      defaults: {
        title: 'Welcome to Our Campaign',
        subtitle: 'Join us in making a difference in your community.',
        backgroundImage: '',
        ctaText: 'Get Involved',
        ctaUrl: '#',
      },
    },
    {
      id: 'default-text',
      type: 'text',
      label: 'Text Block',
      category: 'Content',
      sortOrder: 2,
      schema: {
        heading: { type: 'string', label: 'Heading' },
        body: { type: 'text', label: 'Body Text' },
      },
      defaults: {
        heading: 'About Us',
        body: 'Tell your story here. Explain your mission, values, and what drives your campaign forward.',
      },
    },
    {
      id: 'default-features',
      type: 'features',
      label: 'Features Grid',
      category: 'Content',
      sortOrder: 3,
      schema: {
        features: { type: 'array', label: 'Features', items: { title: 'string', description: 'string', icon: 'string' } },
      },
      defaults: {
        features: [
          { title: 'Community Action', description: 'Organize local events and initiatives.', icon: '' },
          { title: 'Advocacy', description: 'Email your representatives directly.', icon: '' },
          { title: 'Volunteer', description: 'Sign up for shifts and make a difference.', icon: '' },
        ],
      },
    },
    {
      id: 'default-cta',
      type: 'cta',
      label: 'Call to Action',
      category: 'Actions',
      sortOrder: 4,
      schema: {
        heading: { type: 'string', label: 'Heading' },
        description: { type: 'string', label: 'Description' },
        buttonText: { type: 'string', label: 'Button Text' },
        buttonUrl: { type: 'string', label: 'Button URL' },
      },
      defaults: {
        heading: 'Ready to Take Action?',
        description: 'Join thousands of community members making their voices heard.',
        buttonText: 'Join Now',
        buttonUrl: '#',
      },
    },
    {
      id: 'default-testimonials',
      type: 'testimonials',
      label: 'Testimonials',
      category: 'Content',
      sortOrder: 5,
      schema: {
        quotes: { type: 'array', label: 'Quotes', items: { text: 'string', author: 'string', role: 'string' } },
      },
      defaults: {
        quotes: [
          { text: 'This platform made it so easy to contact my representatives.', author: 'Jane D.', role: 'Community Member' },
          { text: 'I signed up for a volunteer shift and it changed my perspective.', author: 'Mark S.', role: 'Volunteer' },
        ],
      },
    },
    {
      id: 'default-contact-form',
      type: 'contact-form',
      label: 'Contact Form',
      category: 'Actions',
      sortOrder: 6,
      schema: {
        heading: { type: 'string', label: 'Heading' },
        fields: { type: 'array', label: 'Fields', items: { name: 'string', type: 'string', required: 'boolean' } },
      },
      defaults: {
        heading: 'Get in Touch',
        fields: [
          { name: 'Name', type: 'text', required: true },
          { name: 'Email', type: 'email', required: true },
          { name: 'Message', type: 'textarea', required: true },
        ],
      },
    },
    {
      id: 'default-video',
      type: 'video',
      label: 'Video Player',
      category: 'Media',
      sortOrder: 7,
      schema: {
        videoId: { type: 'number', label: 'Video ID', required: true },
        playerType: { type: 'select', label: 'Player Type', options: ['standard', 'advanced'], default: 'standard' },
        width: { type: 'string', label: 'Width', default: '100%' },
        height: { type: 'string', label: 'Height', default: 'auto' },
        autoplay: { type: 'boolean', label: 'Autoplay', default: false },
        controls: { type: 'boolean', label: 'Show Controls', default: true },
        showReactions: { type: 'boolean', label: 'Show Reactions (Advanced Only)', default: true },
      },
      defaults: {
        videoId: null,
        playerType: 'standard',
        width: '100%',
        height: 'auto',
        autoplay: false,
        controls: true,
        showReactions: true,
      },
    },
    {
      id: 'default-video-card',
      type: 'video-card',
      label: 'Video Card',
      category: 'Media',
      sortOrder: 8,
      schema: {
        videoId: { type: 'number', label: 'Video ID', required: true },
        title: { type: 'string', label: 'Title' },
        durationSeconds: { type: 'number', label: 'Duration (seconds)', default: 0 },
        quality: { type: 'string', label: 'Quality (e.g. 1080p)' },
        viewCount: { type: 'number', label: 'View Count', default: 0 },
      },
      defaults: {
        videoId: null,
        title: '',
        durationSeconds: 0,
        quality: '',
        viewCount: 0,
      },
    },
    {
      id: 'default-donate-button',
      type: 'donate-button',
      label: 'Donate Button',
      category: 'Payments',
      sortOrder: 9,
      schema: {
        buttonText: { type: 'string', label: 'Button Text', default: 'Donate Now' },
        showAmounts: { type: 'boolean', label: 'Show Suggested Amounts', default: true },
        heading: { type: 'string', label: 'Heading', default: 'Support Our Cause' },
        description: { type: 'string', label: 'Description' },
      },
      defaults: {
        buttonText: 'Donate Now',
        showAmounts: true,
        heading: 'Support Our Cause',
        description: 'Your contribution helps us create lasting change in our community.',
      },
    },
    {
      id: 'default-pricing-table',
      type: 'pricing-table',
      label: 'Pricing Table',
      category: 'Payments',
      sortOrder: 10,
      schema: {
        showYearly: { type: 'boolean', label: 'Show Yearly Toggle', default: true },
        heading: { type: 'string', label: 'Heading', default: 'Choose Your Plan' },
        description: { type: 'string', label: 'Description' },
      },
      defaults: {
        showYearly: true,
        heading: 'Choose Your Plan',
        description: 'Get access to exclusive content and features.',
      },
    },
    {
      id: 'default-product-card',
      type: 'product-card',
      label: 'Product Card',
      category: 'Payments',
      sortOrder: 11,
      schema: {
        productSlug: { type: 'string', label: 'Product Slug', required: true },
        buttonText: { type: 'string', label: 'Button Text', default: 'Buy Now' },
      },
      defaults: {
        productSlug: '',
        buttonText: 'Buy Now',
      },
    },
    {
      id: 'default-campaign-form',
      type: 'campaign-form',
      label: 'Campaign Email Form',
      category: 'Influence',
      sortOrder: 13,
      schema: {
        campaignSlug: { type: 'string', label: 'Campaign Slug', required: true },
        compact: { type: 'boolean', label: 'Compact Mode', default: false },
      },
      defaults: {
        campaignSlug: '',
        compact: false,
      },
    },
    {
      id: 'default-gancio-events',
      type: 'gancio-events',
      label: 'Event Calendar',
      category: 'Content',
      sortOrder: 12,
      schema: {
        maxlength: { type: 'number', label: 'Max Events', default: 10 },
        theme: { type: 'select', label: 'Theme', options: ['dark', 'light'], default: 'dark' },
        tags: { type: 'string', label: 'Filter by Tags (comma-separated)' },
        title: { type: 'string', label: 'Section Title', default: 'Upcoming Events' },
      },
      defaults: {
        maxlength: 10,
        theme: 'dark',
        tags: '',
        title: 'Upcoming Events',
      },
    },
    {
      id: 'default-photo',
      type: 'photo',
      label: 'Photo',
      category: 'Media',
      sortOrder: 14,
      schema: {
        photoId: { type: 'number', label: 'Photo ID', required: true },
        size: { type: 'select', label: 'Size', options: ['thumb', 'medium', 'large'], default: 'large' },
        caption: { type: 'string', label: 'Caption' },
        linkToGallery: { type: 'boolean', label: 'Link to Gallery', default: true },
        alignment: { type: 'select', label: 'Alignment', options: ['left', 'center', 'right'], default: 'center' },
        maxWidth: { type: 'string', label: 'Max Width', default: '100%' },
      },
      defaults: {
        photoId: null,
        size: 'large',
        caption: '',
        linkToGallery: true,
        alignment: 'center',
        maxWidth: '100%',
      },
    },
    {
      id: 'default-photo-card',
      type: 'photo-card',
      label: 'Photo Card',
      category: 'Media',
      sortOrder: 15,
      schema: {
        photoId: { type: 'number', label: 'Photo ID', required: true },
        title: { type: 'string', label: 'Title' },
        description: { type: 'string', label: 'Description' },
        showMetadata: { type: 'boolean', label: 'Show Metadata (format, dimensions)', default: true },
      },
      defaults: {
        photoId: null,
        title: '',
        description: '',
        showMetadata: true,
      },
    },
    {
      id: 'default-photo-album',
      type: 'photo-album',
      label: 'Photo Album',
      category: 'Media',
      sortOrder: 16,
      schema: {
        albumId: { type: 'number', label: 'Album ID', required: true },
        columns: { type: 'select', label: 'Columns', options: ['2', '3', '4'], default: '3' },
        maxPhotos: { type: 'number', label: 'Max Photos', default: 12 },
        showTitle: { type: 'boolean', label: 'Show Album Title', default: true },
      },
      defaults: {
        albumId: null,
        columns: '3',
        maxPhotos: 12,
        showTitle: true,
      },
    },
    {
      id: 'default-scheduling-poll',
      type: 'scheduling-poll',
      label: 'Scheduling Poll',
      category: 'Influence',
      sortOrder: 17,
      schema: {
        pollSlug: { type: 'string', label: 'Poll Slug', required: true },
        showComments: { type: 'boolean', label: 'Show Comments', default: true },
        title: { type: 'string', label: 'Section Title', default: 'Vote on a Meeting Time' },
      },
      defaults: {
        pollSlug: '',
        showComments: true,
        title: 'Vote on a Meeting Time',
      },
    },
    {
      id: 'default-straw-poll-inline',
      type: 'straw-poll-inline',
      label: 'Straw Poll (Inline)',
      category: 'Influence',
      sortOrder: 18,
      schema: {
        pollSlug: { type: 'string', label: 'Poll Slug', required: true },
      },
      defaults: {
        pollSlug: '',
      },
    },
    {
      id: 'default-straw-poll-card',
      type: 'straw-poll-card',
      label: 'Straw Poll (Card)',
      category: 'Influence',
      sortOrder: 19,
      schema: {
        pollSlug: { type: 'string', label: 'Poll Slug', required: true },
      },
      defaults: {
        pollSlug: '',
      },
    },
  ];

  for (const block of defaultBlocks) {
    await prisma.pageBlock.upsert({
      where: { id: block.id },
      update: {},
      create: block,
    });
  }

  console.log(`Created ${defaultBlocks.length} default page blocks`);

  // Seed email templates (skip if no admin user)
  if (admin) {
    await seedEmailTemplates(admin);
  } else {
    console.warn('⚠️  No admin user found - skipping email template seeding');
  }

  // Seed SMS notification templates
  await seedSmsNotificationTemplates();

  // Seed pre-made gallery ads (all inactive by default — admin enables manually)
  await seedGalleryAds();

  console.log('Seed complete.');
}

/**
 * Seed email templates from filesystem
 */
async function seedEmailTemplates(admin: { id: string; email: string }) {
  console.log('Seeding email templates...');

  const templatesDir = path.join(__dirname, '../src/templates/email');

  const templateDefinitions = [
    {
      key: 'campaign-email',
      name: 'Campaign Email to Representative',
      description: 'Email sent when a constituent contacts their elected representative through a campaign',
      category: EmailTemplateCategory.INFLUENCE,
      subjectLine: '{{CAMPAIGN_TITLE}} - Message from {{USER_NAME}}',
      isSystem: true,
      variables: [
        { key: 'CAMPAIGN_TITLE', label: 'Campaign Title', description: 'Title of the advocacy campaign', isRequired: true, isConditional: false, sampleValue: 'Support Climate Action Bill C-12', sortOrder: 0 },
        { key: 'MESSAGE', label: 'Message Body', description: 'The message content written by the constituent', isRequired: true, isConditional: false, sampleValue: 'I urge you to support this important legislation...', sortOrder: 1 },
        { key: 'USER_NAME', label: 'Sender Name', description: 'Name of the constituent sending the email', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 2 },
        { key: 'USER_EMAIL', label: 'Sender Email', description: 'Email address of the constituent', isRequired: true, isConditional: false, sampleValue: 'jane@example.com', sortOrder: 3 },
        { key: 'POSTAL_CODE', label: 'Postal Code', description: 'Postal code of the constituent', isRequired: true, isConditional: false, sampleValue: 'K1A 0B1', sortOrder: 4 },
        { key: 'RECIPIENT_NAME', label: 'Representative Name', description: 'Name of the representative receiving the email', isRequired: false, isConditional: true, sampleValue: 'Hon. John Smith', sortOrder: 5 },
        { key: 'RECIPIENT_LEVEL', label: 'Government Level', description: 'Level of government', isRequired: false, isConditional: true, sampleValue: 'Federal', sortOrder: 6 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 7 },
        { key: 'TIMESTAMP', label: 'Timestamp', description: 'Date and time the email was sent', isRequired: true, isConditional: false, sampleValue: '2025-02-11T10:30:00Z', sortOrder: 8 },
      ],
    },
    {
      key: 'response-verification',
      name: 'Response Verification Email',
      description: 'Email sent to representatives to verify a submitted response',
      category: EmailTemplateCategory.INFLUENCE,
      subjectLine: 'Verify Your Response - {{CAMPAIGN_TITLE}}',
      isSystem: true,
      variables: [
        { key: 'CAMPAIGN_TITLE', label: 'Campaign Title', description: 'Title of the advocacy campaign', isRequired: true, isConditional: false, sampleValue: 'Support Climate Action Bill C-12', sortOrder: 0 },
        { key: 'RESPONSE_TYPE', label: 'Response Type', description: 'Type of response', isRequired: true, isConditional: false, sampleValue: 'SUPPORT', sortOrder: 1 },
        { key: 'RESPONSE_TEXT', label: 'Response Text', description: 'The text of the response submitted', isRequired: true, isConditional: false, sampleValue: 'I fully support this initiative...', sortOrder: 2 },
        { key: 'SUBMITTER_NAME', label: 'Submitter Name', description: 'Name of the person who submitted the response', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 3 },
        { key: 'SUBMITTED_DATE', label: 'Submitted Date', description: 'Date the response was submitted', isRequired: true, isConditional: false, sampleValue: 'February 11, 2025', sortOrder: 4 },
        { key: 'VERIFICATION_URL', label: 'Verification URL', description: 'URL to verify the response', isRequired: true, isConditional: false, sampleValue: 'https://api.cmlite.org/api/responses/123/verify/abc123', sortOrder: 5 },
        { key: 'REPORT_URL', label: 'Report URL', description: 'URL to report the response as invalid', isRequired: true, isConditional: false, sampleValue: 'https://api.cmlite.org/api/responses/123/report/abc123', sortOrder: 6 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 7 },
        { key: 'TIMESTAMP', label: 'Timestamp', description: 'Date and time the verification email was sent', isRequired: true, isConditional: false, sampleValue: '2025-02-11T10:30:00Z', sortOrder: 8 },
      ],
    },
    {
      key: 'shift-signup-confirmation',
      name: 'Shift Signup Confirmation',
      description: 'Email sent when a volunteer signs up for a shift',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'Shift Confirmation - {{SHIFT_TITLE}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'USER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer', isRequired: true, isConditional: false, sampleValue: 'John Smith', sortOrder: 1 },
        { key: 'USER_EMAIL', label: 'Volunteer Email', description: 'Email address of the volunteer', isRequired: true, isConditional: false, sampleValue: 'john@example.com', sortOrder: 2 },
        { key: 'SHIFT_TITLE', label: 'Shift Title', description: 'Title of the volunteer shift', isRequired: true, isConditional: false, sampleValue: 'Weekend Canvassing - Downtown', sortOrder: 3 },
        { key: 'SHIFT_DATE', label: 'Shift Date', description: 'Date of the volunteer shift', isRequired: true, isConditional: false, sampleValue: 'Saturday, February 15, 2025', sortOrder: 4 },
        { key: 'SHIFT_TIME', label: 'Shift Time', description: 'Time of the volunteer shift', isRequired: true, isConditional: false, sampleValue: '10:00 AM — 2:00 PM', sortOrder: 5 },
        { key: 'SHIFT_LOCATION', label: 'Shift Location', description: 'Location of the volunteer shift', isRequired: true, isConditional: false, sampleValue: '123 Main Street', sortOrder: 6 },
        { key: 'IS_NEW_USER', label: 'Is New User', description: 'Whether this is a new user account', isRequired: false, isConditional: true, sampleValue: 'true', sortOrder: 7 },
        { key: 'TEMP_PASSWORD', label: 'Temporary Password', description: 'Temporary password for new user account', isRequired: false, isConditional: true, sampleValue: 'SwiftEagle42', sortOrder: 8 },
        { key: 'LOGIN_URL', label: 'Login URL', description: 'URL to log in to the system', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/login', sortOrder: 9 },
      ],
    },
    {
      key: 'shift-details',
      name: 'Shift Details Reminder',
      description: 'Reminder email sent to all volunteers signed up for a shift',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'Shift Reminder - {{SHIFT_TITLE}} on {{SHIFT_DATE}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'USER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer', isRequired: true, isConditional: false, sampleValue: 'John Smith', sortOrder: 1 },
        { key: 'SHIFT_TITLE', label: 'Shift Title', description: 'Title of the volunteer shift', isRequired: true, isConditional: false, sampleValue: 'Weekend Canvassing - Downtown', sortOrder: 2 },
        { key: 'SHIFT_DATE', label: 'Shift Date', description: 'Date of the volunteer shift', isRequired: true, isConditional: false, sampleValue: 'Saturday, February 15, 2025', sortOrder: 3 },
        { key: 'SHIFT_START_TIME', label: 'Start Time', description: 'Start time of the shift', isRequired: true, isConditional: false, sampleValue: '10:00 AM', sortOrder: 4 },
        { key: 'SHIFT_END_TIME', label: 'End Time', description: 'End time of the shift', isRequired: true, isConditional: false, sampleValue: '2:00 PM', sortOrder: 5 },
        { key: 'SHIFT_LOCATION', label: 'Shift Location', description: 'Location of the volunteer shift', isRequired: true, isConditional: false, sampleValue: '123 Main Street', sortOrder: 6 },
        { key: 'SHIFT_DESCRIPTION', label: 'Shift Description', description: 'Description of the shift', isRequired: false, isConditional: true, sampleValue: 'We will be canvassing the downtown area...', sortOrder: 7 },
        { key: 'CURRENT_VOLUNTEERS', label: 'Current Volunteers', description: 'Number of volunteers currently signed up', isRequired: true, isConditional: false, sampleValue: '8', sortOrder: 8 },
        { key: 'MAX_VOLUNTEERS', label: 'Max Volunteers', description: 'Maximum number of volunteers allowed', isRequired: true, isConditional: false, sampleValue: '10', sortOrder: 9 },
        { key: 'SHIFT_STATUS', label: 'Shift Status', description: 'Status of the shift', isRequired: true, isConditional: false, sampleValue: 'OPEN', sortOrder: 10 },
      ],
    },
    {
      key: 'email-verification',
      name: 'Email Verification',
      description: 'Sent to new users to verify their email address after self-registration',
      category: EmailTemplateCategory.SYSTEM,
      subjectLine: 'Verify your email — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'RECIPIENT_NAME', label: 'User Name', description: 'Name of the user being verified', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 0 },
        { key: 'VERIFICATION_URL', label: 'Verification URL', description: 'URL the user clicks to verify their email', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/verify-email?token=abc123', sortOrder: 1 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 2 },
        { key: 'EXPIRY_HOURS', label: 'Expiry Hours', description: 'Number of hours until the verification link expires', isRequired: true, isConditional: false, sampleValue: '24', sortOrder: 3 },
      ],
    },
    {
      key: 'password-reset',
      name: 'Password Reset',
      description: 'Sent when a user requests a password reset link',
      category: EmailTemplateCategory.SYSTEM,
      subjectLine: 'Reset your password — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'RECIPIENT_NAME', label: 'User Name', description: 'Name of the user requesting a reset', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 0 },
        { key: 'RESET_URL', label: 'Reset URL', description: 'URL the user clicks to reset their password', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/reset-password?token=abc123', sortOrder: 1 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 2 },
      ],
    },
    {
      key: 'account-approved',
      name: 'Account Approved',
      description: 'Sent to a user when an admin approves their account after email verification',
      category: EmailTemplateCategory.SYSTEM,
      subjectLine: 'Account approved — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'RECIPIENT_NAME', label: 'User Name', description: 'Name of the approved user', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 0 },
        { key: 'LOGIN_URL', label: 'Login URL', description: 'URL to the login page', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/login', sortOrder: 1 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 2 },
      ],
    },
    {
      key: 'account-pending-approval',
      name: 'Account Pending Approval (Admin Notification)',
      description: 'Sent to admins when a new user verifies their email and is awaiting approval',
      category: EmailTemplateCategory.SYSTEM,
      subjectLine: 'New user awaiting approval — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'NEW_USER_NAME', label: 'New User Name', description: 'Name of the new user requesting approval', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 0 },
        { key: 'NEW_USER_EMAIL', label: 'New User Email', description: 'Email of the new user', isRequired: true, isConditional: false, sampleValue: 'jane@example.com', sortOrder: 1 },
        { key: 'REGISTERED_AT', label: 'Registration Date', description: 'Date the user registered', isRequired: true, isConditional: false, sampleValue: 'February 16, 2026', sortOrder: 2 },
        { key: 'ADMIN_URL', label: 'Admin URL', description: 'URL to the admin users page filtered to pending approval', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/app/users?status=PENDING_APPROVAL', sortOrder: 3 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 4 },
      ],
    },
    {
      key: 'donation-receipt',
      name: 'Donation Receipt',
      description: 'Receipt email sent to donors after a successful donation payment',
      category: EmailTemplateCategory.PAYMENT,
      subjectLine: 'Donation Receipt — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'RECIPIENT_NAME', label: 'Donor Name', description: 'Name of the donor', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 0 },
        { key: 'AMOUNT', label: 'Amount', description: 'Donation amount formatted with dollar sign', isRequired: true, isConditional: false, sampleValue: '$25.00', sortOrder: 1 },
        { key: 'ORDER_ID', label: 'Order ID', description: 'Unique reference ID for the donation', isRequired: true, isConditional: false, sampleValue: 'clxyz123abc', sortOrder: 2 },
        { key: 'DONATION_DATE', label: 'Donation Date', description: 'Date the donation was completed', isRequired: true, isConditional: false, sampleValue: 'February 17, 2026', sortOrder: 3 },
        { key: 'DONOR_MESSAGE', label: 'Donor Message', description: 'Optional message from the donor', isRequired: false, isConditional: true, sampleValue: 'Keep up the great work!', sortOrder: 4 },
        { key: 'IS_ANONYMOUS', label: 'Is Anonymous', description: 'Whether the donation is anonymous', isRequired: false, isConditional: true, sampleValue: 'true', sortOrder: 5 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 6 },
      ],
    },
    {
      key: 'product-receipt',
      name: 'Product Purchase Receipt',
      description: 'Receipt email sent to buyers after a successful product purchase',
      category: EmailTemplateCategory.PAYMENT,
      subjectLine: 'Purchase Receipt — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'RECIPIENT_NAME', label: 'Buyer Name', description: 'Name of the buyer', isRequired: true, isConditional: false, sampleValue: 'John Smith', sortOrder: 0 },
        { key: 'AMOUNT', label: 'Amount', description: 'Purchase amount formatted with dollar sign', isRequired: true, isConditional: false, sampleValue: '$49.99', sortOrder: 1 },
        { key: 'ORDER_ID', label: 'Order ID', description: 'Unique order reference ID', isRequired: true, isConditional: false, sampleValue: 'clxyz456def', sortOrder: 2 },
        { key: 'PRODUCT_TITLE', label: 'Product Title', description: 'Title of the purchased product', isRequired: true, isConditional: false, sampleValue: 'Community Toolkit', sortOrder: 3 },
        { key: 'PRODUCT_TYPE', label: 'Product Type', description: 'Type of product (DIGITAL, EVENT, DONATION)', isRequired: true, isConditional: false, sampleValue: 'DIGITAL', sortOrder: 4 },
        { key: 'PURCHASE_DATE', label: 'Purchase Date', description: 'Date of purchase', isRequired: true, isConditional: false, sampleValue: 'February 17, 2026', sortOrder: 5 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 6 },
      ],
    },
    {
      key: 'subscription-welcome',
      name: 'Subscription Welcome',
      description: 'Welcome email sent when a user subscribes to a plan',
      category: EmailTemplateCategory.PAYMENT,
      subjectLine: 'Welcome to {{PLAN_NAME}} — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'RECIPIENT_NAME', label: 'User Name', description: 'Name of the subscriber', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 0 },
        { key: 'PLAN_NAME', label: 'Plan Name', description: 'Name of the subscription plan', isRequired: true, isConditional: false, sampleValue: 'Pro Plan', sortOrder: 1 },
        { key: 'AMOUNT', label: 'Amount', description: 'Subscription price formatted with dollar sign', isRequired: true, isConditional: false, sampleValue: '$9.99', sortOrder: 2 },
        { key: 'FREQUENCY', label: 'Billing Frequency', description: 'How often the subscription renews', isRequired: true, isConditional: false, sampleValue: 'per month', sortOrder: 3 },
        { key: 'RENEWAL_DATE', label: 'Renewal Date', description: 'Next renewal date', isRequired: true, isConditional: false, sampleValue: 'March 17, 2026', sortOrder: 4 },
        { key: 'SUBSCRIPTION_ID', label: 'Subscription ID', description: 'Stripe subscription ID', isRequired: true, isConditional: false, sampleValue: 'sub_1234567890', sortOrder: 5 },
        { key: 'LOGIN_URL', label: 'Login URL', description: 'URL to log in to the platform', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/login', sortOrder: 6 },
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 7 },
      ],
    },
    {
      key: 'admin-shift-signup-alert',
      name: 'Admin: New Shift Signup Alert',
      description: 'Notification sent to admins when a volunteer signs up for a shift',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'New shift signup — {{SHIFT_TITLE}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'SHIFT_TITLE', label: 'Shift Title', description: 'Title of the shift', isRequired: true, isConditional: false, sampleValue: 'Weekend Canvassing - Downtown', sortOrder: 1 },
        { key: 'SHIFT_DATE', label: 'Shift Date', description: 'Date of the shift', isRequired: true, isConditional: false, sampleValue: 'Saturday, February 22, 2026', sortOrder: 2 },
        { key: 'VOLUNTEER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer who signed up', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 3 },
        { key: 'VOLUNTEER_EMAIL', label: 'Volunteer Email', description: 'Email of the volunteer', isRequired: true, isConditional: false, sampleValue: 'jane@example.com', sortOrder: 4 },
        { key: 'SIGNUP_SOURCE', label: 'Signup Source', description: 'How the volunteer signed up (Public Form, Authenticated Volunteer)', isRequired: true, isConditional: false, sampleValue: 'Public Form', sortOrder: 5 },
        { key: 'ADMIN_URL', label: 'Admin URL', description: 'URL to the admin shifts page', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/app/map/shifts', sortOrder: 6 },
      ],
    },
    {
      key: 'admin-response-submitted-alert',
      name: 'Admin: Response Submitted Alert',
      description: 'Notification sent to admins when a new response is submitted to the response wall',
      category: EmailTemplateCategory.INFLUENCE,
      subjectLine: 'New response submitted — {{CAMPAIGN_TITLE}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'CAMPAIGN_TITLE', label: 'Campaign Title', description: 'Title of the campaign', isRequired: true, isConditional: false, sampleValue: 'Support Climate Action Bill C-12', sortOrder: 1 },
        { key: 'REPRESENTATIVE_NAME', label: 'Representative Name', description: 'Name of the representative the response is about', isRequired: true, isConditional: false, sampleValue: 'Hon. John Smith', sortOrder: 2 },
        { key: 'RESPONSE_TYPE', label: 'Response Type', description: 'Type of response (Support, Oppose, etc.)', isRequired: true, isConditional: false, sampleValue: 'SUPPORT', sortOrder: 3 },
        { key: 'SUBMITTER_NAME', label: 'Submitter Name', description: 'Name of the person who submitted', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 4 },
        { key: 'ADMIN_URL', label: 'Admin URL', description: 'URL to the admin responses page', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/app/influence/responses', sortOrder: 5 },
      ],
    },
    {
      key: 'admin-sign-requested-alert',
      name: 'Admin: Sign Requested Alert',
      description: 'Notification sent to admins when a resident requests a yard sign during canvassing',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'Sign requested — {{ADDRESS}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'VOLUNTEER_NAME', label: 'Canvasser Name', description: 'Name of the volunteer who recorded the sign request', isRequired: true, isConditional: false, sampleValue: 'John Smith', sortOrder: 1 },
        { key: 'ADDRESS', label: 'Address', description: 'Street address where sign was requested', isRequired: true, isConditional: false, sampleValue: '123 Main Street', sortOrder: 2 },
        { key: 'SHIFT_TITLE', label: 'Shift Title', description: 'Title of the canvassing shift', isRequired: true, isConditional: false, sampleValue: 'Weekend Canvassing - Downtown', sortOrder: 3 },
        { key: 'SIGN_SIZE', label: 'Sign Size', description: 'Requested sign size', isRequired: false, isConditional: true, sampleValue: 'Large', sortOrder: 4 },
        { key: 'ADMIN_URL', label: 'Admin URL', description: 'URL to the admin canvass dashboard', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/app/canvass/dashboard', sortOrder: 5 },
      ],
    },
    {
      key: 'volunteer-session-summary',
      name: 'Volunteer: Canvass Session Summary',
      description: 'Summary email sent to a volunteer after completing a canvassing session',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'Canvass session summary — {{CUT_NAME}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'VOLUNTEER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 1 },
        { key: 'CUT_NAME', label: 'Cut/Area Name', description: 'Name of the canvassing area', isRequired: true, isConditional: false, sampleValue: 'Downtown Core', sortOrder: 2 },
        { key: 'SESSION_DATE', label: 'Session Date', description: 'Date of the session', isRequired: true, isConditional: false, sampleValue: 'Saturday, February 22, 2026', sortOrder: 3 },
        { key: 'VISIT_COUNT', label: 'Visit Count', description: 'Number of doors visited', isRequired: true, isConditional: false, sampleValue: '42', sortOrder: 4 },
        { key: 'DURATION_MINUTES', label: 'Duration (minutes)', description: 'Session duration in minutes', isRequired: true, isConditional: false, sampleValue: '95', sortOrder: 5 },
        { key: 'DISTANCE_KM', label: 'Distance (km)', description: 'Distance walked in kilometers', isRequired: true, isConditional: false, sampleValue: '2.3', sortOrder: 6 },
        { key: 'OUTCOME_BREAKDOWN', label: 'Outcome Breakdown', description: 'HTML table (email) or text list (plain text) of visit outcomes', isRequired: false, isConditional: true, sampleValue: 'Spoke With: 20, Not Home: 15, Refused: 7', sortOrder: 7 },
      ],
    },
    {
      key: 'volunteer-cancellation-ack',
      name: 'Volunteer: Signup Cancellation Acknowledgement',
      description: 'Confirmation email sent to a volunteer when their shift signup is cancelled',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'Signup cancelled — {{SHIFT_TITLE}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'VOLUNTEER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 1 },
        { key: 'SHIFT_TITLE', label: 'Shift Title', description: 'Title of the cancelled shift signup', isRequired: true, isConditional: false, sampleValue: 'Weekend Canvassing - Downtown', sortOrder: 2 },
        { key: 'SHIFT_DATE', label: 'Shift Date', description: 'Date of the shift', isRequired: true, isConditional: false, sampleValue: 'Saturday, February 22, 2026', sortOrder: 3 },
        { key: 'SHIFT_TIME', label: 'Shift Time', description: 'Time range of the shift', isRequired: true, isConditional: false, sampleValue: '10:00 AM — 2:00 PM', sortOrder: 4 },
        { key: 'SIGNUP_URL', label: 'Signup URL', description: 'URL to browse available shifts', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/shifts', sortOrder: 5 },
      ],
    },
    {
      key: 'volunteer-shift-thank-you',
      name: 'Volunteer: Post-Shift Thank You',
      description: 'Thank-you email sent to a volunteer 2 hours after their shift ends',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'Thank you for volunteering — {{SHIFT_TITLE}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'VOLUNTEER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 1 },
        { key: 'SHIFT_TITLE', label: 'Shift Title', description: 'Title of the shift', isRequired: true, isConditional: false, sampleValue: 'Weekend Canvassing - Downtown', sortOrder: 2 },
        { key: 'SHIFT_DATE', label: 'Shift Date', description: 'Date of the shift', isRequired: true, isConditional: false, sampleValue: 'Saturday, February 22, 2026', sortOrder: 3 },
        { key: 'SHIFT_TIME', label: 'Shift Time', description: 'Time range of the shift', isRequired: true, isConditional: false, sampleValue: '10:00 AM — 2:00 PM', sortOrder: 4 },
        { key: 'SHIFT_LOCATION', label: 'Shift Location', description: 'Meeting location for the shift', isRequired: false, isConditional: true, sampleValue: 'City Hall', sortOrder: 5 },
        { key: 'SIGNUP_URL', label: 'Signup URL', description: 'URL to browse upcoming shifts', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/shifts', sortOrder: 6 },
      ],
    },
    {
      key: 'volunteer-reengagement',
      name: 'Volunteer: Re-Engagement',
      description: 'Re-engagement email sent to volunteers who have been inactive for a configurable period',
      category: EmailTemplateCategory.MAP,
      subjectLine: 'We miss you — {{ORGANIZATION_NAME}}',
      isSystem: true,
      variables: [
        { key: 'ORGANIZATION_NAME', label: 'Organization Name', description: 'Name of the organization', isRequired: true, isConditional: false, sampleValue: 'Changemaker Lite', sortOrder: 0 },
        { key: 'VOLUNTEER_NAME', label: 'Volunteer Name', description: 'Name of the volunteer', isRequired: true, isConditional: false, sampleValue: 'Jane Doe', sortOrder: 1 },
        { key: 'LAST_ACTIVITY_DATE', label: 'Last Activity Date', description: 'Date of the volunteer\'s last activity', isRequired: true, isConditional: false, sampleValue: 'January 15, 2026', sortOrder: 2 },
        { key: 'LAST_ACTIVITY_TYPE', label: 'Last Activity Type', description: 'Type of the volunteer\'s last activity', isRequired: true, isConditional: false, sampleValue: 'Shift Signup', sortOrder: 3 },
        { key: 'SIGNUP_URL', label: 'Signup URL', description: 'URL to browse upcoming shifts', isRequired: true, isConditional: false, sampleValue: 'https://app.cmlite.org/shifts', sortOrder: 4 },
      ],
    },
  ];

  let seededCount = 0;
  let skippedCount = 0;

  for (const templateDef of templateDefinitions) {
    try {
      // Check if template already exists
      const existing = await prisma.emailTemplate.findUnique({
        where: { key: templateDef.key },
      });

      if (existing) {
        skippedCount++;
        continue;
      }

      // Read HTML and TXT files from filesystem
      const htmlPath = path.join(templatesDir, `${templateDef.key}.html`);
      const txtPath = path.join(templatesDir, `${templateDef.key}.txt`);

      if (!fs.existsSync(htmlPath) || !fs.existsSync(txtPath)) {
        console.warn(`  ⚠️  Template files not found for ${templateDef.key}`);
        continue;
      }

      const htmlContent = fs.readFileSync(htmlPath, 'utf-8');
      const textContent = fs.readFileSync(txtPath, 'utf-8');

      // Create template with variables and initial version
      await prisma.$transaction(async (tx) => {
        const template = await tx.emailTemplate.create({
          data: {
            key: templateDef.key,
            name: templateDef.name,
            description: templateDef.description,
            category: templateDef.category,
            subjectLine: templateDef.subjectLine,
            htmlContent,
            textContent,
            isSystem: templateDef.isSystem,
            isActive: true,
            createdByUserId: admin.id,
            variables: {
              create: templateDef.variables,
            },
          },
        });

        // Create initial version
        await tx.emailTemplateVersion.create({
          data: {
            templateId: template.id,
            versionNumber: 1,
            subjectLine: templateDef.subjectLine,
            htmlContent,
            textContent,
            changeNotes: 'Initial migration from filesystem',
            createdByUserId: admin.id,
          },
        });
      });

      seededCount++;
    } catch (error) {
      console.error(`  ❌ Error seeding template ${templateDef.key}:`, error);
    }
  }

  console.log(`Email templates seeded: ${seededCount} created, ${skippedCount} skipped`);
}

/**
 * Seed default SMS notification templates
 */
async function seedSmsNotificationTemplates() {
  console.log('Seeding SMS notification templates...');

  const templates = [
    {
      name: 'shift-reminder',
      template: 'Hi {name}, reminder: {shiftTitle} is tomorrow at {shiftTime}. Location: {shiftLocation}',
      description: 'Sent before a volunteer shift as a reminder',
      category: 'notification',
    },
    {
      name: 'shift-signup-confirm',
      template: "Hi {name}, you're signed up for {shiftTitle} on {shiftDate} at {shiftTime}. See you there!",
      description: 'Sent when a volunteer signs up for a shift',
      category: 'notification',
    },
    {
      name: 'volunteer-welcome',
      template: 'Welcome to the team, {name}! Thanks for signing up as a volunteer.',
      description: 'Sent when a new volunteer account is created',
      category: 'notification',
    },
  ];

  let seeded = 0;
  let skipped = 0;

  for (const t of templates) {
    const existing = await prisma.smsMessageTemplate.findFirst({ where: { name: t.name } });
    if (existing) {
      skipped++;
      continue;
    }
    await prisma.smsMessageTemplate.create({
      data: {
        name: t.name,
        template: t.template,
        description: t.description,
        category: t.category,
      },
    });
    seeded++;
  }

  console.log(`SMS notification templates seeded: ${seeded} created, ${skipped} skipped`);
}

/**
 * Seed pre-made gallery ads
 */
async function seedGalleryAds() {
  console.log('Seeding gallery ads...');

  const defaultAds = [
    {
      type: 'system',
      variant: 'standard',
      title: 'Join the Community',
      subtitle: 'Create a free account to upvote, comment, and save favorites',
      ctaText: 'Sign Up Free',
      ctaStyle: 'primary',
      linkUrl: '/login',
      visibility: 'anonymous',
      frequency: 8,
      position: 1,
      iconEmoji: null,
      bgColor: null,
      imagePath: null,
      placements: ['gallery', 'docs'],
    },
    {
      type: 'payment_subscribe',
      variant: 'highlight',
      title: 'Unlock Premium Content',
      subtitle: 'Subscribe for exclusive videos, early access, and more',
      ctaText: 'View Plans',
      ctaStyle: 'primary',
      linkUrl: '/pricing',
      visibility: 'non_subscriber',
      frequency: 12,
      position: 2,
      iconEmoji: null,
      bgColor: null,
      imagePath: null,
      placements: ['gallery', 'pricing', 'landing_page', 'docs'],
    },
    {
      type: 'payment_donate',
      variant: 'standard',
      title: 'Support Our Mission',
      subtitle: 'Your donation helps us create more content',
      ctaText: 'Donate Now',
      ctaStyle: 'primary',
      linkUrl: '/donate',
      visibility: 'everyone',
      frequency: 18,
      position: 3,
      iconEmoji: null,
      bgColor: null,
      imagePath: null,
      placements: ['gallery', 'donate', 'landing_page', 'docs'],
    },
    {
      type: 'payment_shop',
      variant: 'standard',
      title: 'Browse the Shop',
      subtitle: 'Exclusive merchandise, downloads, and event tickets',
      ctaText: 'Shop Now',
      ctaStyle: 'primary',
      linkUrl: '/shop',
      visibility: 'everyone',
      frequency: 24,
      position: 4,
      iconEmoji: null,
      bgColor: null,
      imagePath: null,
      placements: ['gallery', 'shop', 'landing_page'],
    },
    {
      type: 'system',
      variant: 'standard',
      title: 'Take Action',
      subtitle: 'Join an advocacy campaign and make your voice heard',
      ctaText: 'View Campaigns',
      ctaStyle: 'primary',
      linkUrl: '/campaigns',
      visibility: 'everyone',
      frequency: 18,
      position: 5,
      iconEmoji: null,
      bgColor: null,
      imagePath: null,
      placements: ['gallery', 'campaigns_list', 'shifts', 'landing_page', 'docs'],
    },
    {
      type: 'system',
      variant: 'standard',
      title: 'Volunteer With Us',
      subtitle: 'Sign up for a shift and help make a difference',
      ctaText: 'See Shifts',
      ctaStyle: 'primary',
      linkUrl: '/shifts',
      visibility: 'everyone',
      frequency: 24,
      position: 6,
      iconEmoji: null,
      bgColor: null,
      imagePath: null,
      placements: ['gallery', 'shifts', 'campaigns_list', 'landing_page'],
    },
  ];

  let seeded = 0;
  let skipped = 0;

  for (const ad of defaultAds) {
    const existing = await prisma.ad.findFirst({
      where: { type: ad.type, title: ad.title },
    });

    if (existing) {
      skipped++;
      continue;
    }

    await prisma.ad.create({
      data: {
        ...ad,
        isSystemAd: true,
        isActive: false,
      },
    });
    seeded++;
  }

  console.log(`Gallery ads seeded: ${seeded} created, ${skipped} skipped`);
}

main()
  .catch((e) => {
    console.error('Seed error:', e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
