import { z } from "zod";
import prisma from "~/server/utils/prisma";

// Input validation schema
const createTemplateSchema = z.object({
  title: z.string().min(1, "Title is required").max(100, "Title must be less than 100 characters"),
  description: z.string().optional(),
  subject: z.string().min(1, "Subject is required").max(255, "Subject must be less than 255 characters"),
  preheader: z.string().max(255, "Preheader must be less than 255 characters").optional(),
  category: z.string().min(1, "Category is required"),
  channels: z.array(z.enum(["email", "sms", "push"])).min(1, "At least one channel is required"),
  status: z.enum(["Draft", "Active", "Archived"]).default("Draft"),
  version: z.string().default("1.0"),
  content: z.string().min(1, "Content is required"),
  tags: z.string().optional(),
  isPersonal: z.boolean().default(false),
  // Email specific settings
  fromName: z.string().optional(),
  replyTo: z.string().email("Invalid reply-to email format").optional().or(z.literal("")),
  trackOpens: z.boolean().default(true),
  // Push notification specific settings
  pushTitle: z.string().optional(),
  pushIcon: z.string().url("Invalid push icon URL").optional().or(z.literal("")),
  pushUrl: z.string().url("Invalid push URL").optional().or(z.literal("")),
  // SMS specific settings
  smsContent: z.string().max(160, "SMS content must be 160 characters or less").optional(),
});

// Helper function to generate unique value from title
function generateUniqueValue(title) {
  return title
    .toLowerCase()
    .replace(/[^a-z0-9\s]/g, '')
    .replace(/\s+/g, '_')
    .substring(0, 50);
}

// Helper function to validate template content
function validateTemplateContent(content, channels) {
  const errors = [];
  
  // Check for balanced variable syntax
  const variableMatches = content.match(/\{\{[^}]*\}\}/g) || [];
  for (const match of variableMatches) {
    if (!match.endsWith('}}')) {
      errors.push(`Unmatched variable syntax: ${match}`);
    }
  }
  
  return errors;
}

export default defineEventHandler(async (event) => {
  try {
    // Read and validate request body
    const body = await readBody(event);
    
    console.log("Template creation request:", body);

    // Validate input data
    const validationResult = createTemplateSchema.safeParse(body);
    if (!validationResult.success) {
      const errors = validationResult.error.errors.map(err => 
        `${err.path.join('.')}: ${err.message}`
      );
      
      throw createError({
        statusCode: 400,
        statusMessage: "Validation failed",
        data: {
          errors: errors
        }
      });
    }

    const validatedData = validationResult.data;

    // Get current user (assuming auth middleware provides this)
    const user = event.context.user;
    if (!user || !user.userID) {
      throw createError({
        statusCode: 401,
        statusMessage: "Authentication required",
      });
    }

    console.log("User authenticated:", user.userID);

    // Validate template content
    const contentErrors = validateTemplateContent(validatedData.content, validatedData.channels);
    if (contentErrors.length > 0) {
      throw createError({
        statusCode: 400,
        statusMessage: "Content validation failed",
        data: {
          errors: contentErrors
        }
      });
    }

    // Generate unique value for the template
    let uniqueValue = generateUniqueValue(validatedData.title);
    
    // Check if value already exists and make it unique
    let counter = 1;
    let finalValue = uniqueValue;
    while (true) {
      const existingTemplate = await prisma.notification_templates.findUnique({
        where: { value: finalValue }
      });
      
      if (!existingTemplate) {
        break;
      }
      
      finalValue = `${uniqueValue}_${counter}`;
      counter++;
      
      // Safety check to prevent infinite loop
      if (counter > 100) {
        finalValue = `${uniqueValue}_${Date.now()}`;
        break;
      }
    }

    // Prepare data for database insertion
    const templateData = {
      name: validatedData.title,
      value: finalValue,
      description: validatedData.description || null,
      subject: validatedData.subject,
      preheader: validatedData.preheader || null,
      email_content: validatedData.content,
      push_title: validatedData.pushTitle || null,
      push_body: validatedData.content ? validatedData.content.replace(/<[^>]*>/g, '').substring(0, 300) : null,
      push_icon: validatedData.pushIcon || null,
      push_url: validatedData.pushUrl || null,
      sms_content: validatedData.smsContent || null,
      category: validatedData.category,
      channels: validatedData.channels,
      status: validatedData.status,
      version: validatedData.version,
      tags: validatedData.tags || null,
      is_personal: validatedData.isPersonal,
      from_name: validatedData.fromName || null,
      reply_to: validatedData.replyTo || null,
      track_opens: validatedData.trackOpens,
      is_active: validatedData.status === "Active" ? 1 : validatedData.status === "Draft" ? 0 : 2,
      created_by: user.userID.toString(),
      updated_by: user.userID.toString(),
    };

    console.log("Creating template with data:", templateData);

    // Create the template
    const newTemplate = await prisma.notification_templates.create({
      data: templateData
    });

    console.log("Template created successfully:", newTemplate.id);

    // Return success response
    return {
      success: true,
      data: {
        id: newTemplate.id,
        message: "Template created successfully",
        template: {
          id: newTemplate.id,
          name: newTemplate.name,
          value: newTemplate.value,
          status: newTemplate.status,
          category: newTemplate.category,
          channels: newTemplate.channels,
          version: newTemplate.version,
          created_at: newTemplate.created_at
        }
      },
    };

  } catch (error) {
    console.error("Template creation error:", error);
    console.error("Error details:", {
      message: error.message,
      stack: error.stack,
      cause: error.cause,
      code: error.code,
      statusCode: error.statusCode
    });

    // Handle Prisma errors
    if (error.code && error.code.startsWith('P')) {
      console.error("Prisma error code:", error.code);
      
      if (error.code === 'P2002') {
        throw createError({
          statusCode: 400,
          statusMessage: "Template with this name already exists",
          data: {
            error: "A template with this name already exists. Please choose a different name.",
            code: error.code
          }
        });
      }
      
      throw createError({
        statusCode: 400,
        statusMessage: "Database operation failed",
        data: {
          error: error.message,
          code: error.code
        }
      });
    }

    // Handle known errors with status codes
    if (error.statusCode) {
      throw error;
    }

    // Generic server error
    throw createError({
      statusCode: 500,
      statusMessage: "Failed to create template",
      data: {
        error: error.message
      }
    });
  } finally {
  }
});
