/**
 * Referral Invite tRPC Router
 * Handles referral invitations via email, SMS, and WhatsApp
 */

import { router, protectedProcedure, publicProcedure } from '../_core/trpc.ts';
import { z } from 'zod';
import {
  createReferralInvite,
  sendInvite,
  generatePersonalizedInviteMessage,
  getInviteTemplates,
  applyTemplate,
  calculateInviteStats,
  type InviteChannel,
} from '../referralInviteSystem.ts';

export const referralInviteRouter = router({
  /**
   * Create and send referral invite
   */
  sendInvite: protectedProcedure
    .input(
      z.object({
        inviteeEmail: z.string().email().optional(),
        inviteePhone: z.string().optional(),
        channel: z.enum(['email', 'sms', 'whatsapp']),
        customMessage: z.string().optional(),
        templateId: z.string().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      // Validate that we have contact info for the channel
      if (input.channel === 'email' && !input.inviteeEmail) {
        throw new Error('Email address required for email invites');
      }
      if ((input.channel === 'sms' || input.channel === 'whatsapp') && !input.inviteePhone) {
        throw new Error('Phone number required for SMS/WhatsApp invites');
      }

      // Create invite
      const invite = await createReferralInvite(
        ctx.user.id,
        ctx.user.name || 'Friend',
        ctx.user.email || '',
        input.inviteeEmail,
        input.inviteePhone,
        input.channel as InviteChannel,
        input.customMessage
      );

      // Send invite
      const sent = await sendInvite(invite);

      if (!sent) {
        throw new Error(`Failed to send ${input.channel} invite`);
      }

      return {
        success: true,
        invite: {
          id: invite.id,
          inviteCode: invite.inviteCode,
          inviteLink: invite.inviteLink,
          status: invite.status,
          expiresAt: invite.expiresAt,
        },
      };
    }),

  /**
   * Get invite templates
   */
  getTemplates: publicProcedure
    .input(
      z.object({
        channel: z.enum(['email', 'sms', 'whatsapp']).optional(),
      })
    )
    .query(({ input }) => {
      let templates = getInviteTemplates();

      if (input.channel) {
        templates = templates.filter((t) => t.channel === input.channel);
      }

      return templates;
    }),

  /**
   * Generate personalized message
   */
  generateMessage: protectedProcedure
    .input(
      z.object({
        templateId: z.string().optional(),
        customMessage: z.string().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const message = await generatePersonalizedInviteMessage(ctx.user.name || 'Friend', input.customMessage);

      return {
        message,
      };
    }),

  /**
   * Get invite history
   */
  getHistory: protectedProcedure
    .input(
      z.object({
        limit: z.number().int().positive().max(500).default(50),
        status: z.enum(['pending', 'sent', 'accepted', 'expired']).optional(),
      })
    )
    .query(async ({ input, ctx }) => {
      // In production, would query from database
      // For now, return mock data
      return {
        invites: [],
        total: 0,
      };
    }),

  /**
   * Get invite statistics
   */
  getStats: protectedProcedure.query(async ({ ctx }) => {
    // In production, would calculate from database
    return {
      totalInvites: 0,
      sentInvites: 0,
      acceptedInvites: 0,
      pendingInvites: 0,
      conversionRate: 0,
      byChannel: {
        email: 0,
        sms: 0,
        whatsapp: 0,
      },
    };
  }),

  /**
   * Resend invite
   */
  resendInvite: protectedProcedure
    .input(
      z.object({
        inviteId: z.string(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      // In production, would fetch invite from database and resend
      return {
        success: true,
        message: 'Invite resent successfully',
      };
    }),

  /**
   * Cancel invite
   */
  cancelInvite: protectedProcedure
    .input(
      z.object({
        inviteId: z.string(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      // In production, would mark invite as cancelled in database
      return {
        success: true,
        message: 'Invite cancelled',
      };
    }),

  /**
   * Track invite click (public)
   */
  trackClick: publicProcedure
    .input(
      z.object({
        inviteCode: z.string(),
      })
    )
    .mutation(async ({ input }) => {
      // In production, would update tracking data in database
      return {
        success: true,
      };
    }),

  /**
   * Validate invite code
   */
  validateCode: publicProcedure
    .input(
      z.object({
        inviteCode: z.string(),
      })
    )
    .query(async ({ input }) => {
      // In production, would validate against database
      return {
        valid: true,
        referrerId: null,
        referrerName: null,
      };
    }),
});
