import { router, protectedProcedure, adminProcedure } from "../_core/trpc.ts";
import { z } from 'zod';
import { TRPCError } from '@trpc/server';
import { emitAlert } from "../_core/alertEmitter.ts";
import { logActivity } from "../_core/activityLogger.ts";
import { sendWelcomeEmail, sendSecurityTipsEmail, sendRoleTrainingEmail } from "../_core/welcomeEmail.ts";

export const adminInvitesRouter = router({
  /**
   * Create and send admin invite
   * Super admin only
   */
  createInvite: adminProcedure
    .input(
      z.object({
        email: z.string().email(),
        role: z.enum(['admin', 'moderator', 'finance_team', 'developer', 'support_lead']),
        fullName: z.string().min(1),
        message: z.string().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // Generate unique invite token
        const inviteToken = Buffer.from(
          `${input.email}:${Date.now()}:${Math.random()}`
        ).toString('base64');

        const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000); // 7 days

        // Log activity
        await logActivity({
          adminId: ctx.user.id,
          action: 'ADMIN_INVITE_CREATED',
          resourceType: 'admin_invite',
          resourceId: inviteToken,
          details: {
            inviteeEmail: input.email,
            inviteeRole: input.role,
            inviteeName: input.fullName,
            expiresAt: expiresAt.toISOString(),
          },
        });

        // Emit alert
        await emitAlert({
          type: 'admin_invited',
          title: 'Admin Invite Sent',
          message: `Invitation sent to ${input.fullName} (${input.email}) for role: ${input.role}`,
          severity: 'info',
          resourceType: 'admin_invite',
          resourceId: inviteToken,
        });

        return {
          success: true,
          inviteToken,
          inviteUrl: `${ctx.req.headers.origin}/admin/accept-invite?token=${inviteToken}`,
          expiresAt: expiresAt.toISOString(),
        };
      } catch (error) {
        console.error('[AdminInvites] Error creating invite:', error);
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to create admin invite',
        });
      }
    }),

  /**
   * Send invite email with all onboarding materials
   */
  sendInviteEmail: adminProcedure
    .input(
      z.object({
        email: z.string().email(),
        fullName: z.string(),
        role: z.string(),
        inviteUrl: z.string().url(),
        message: z.string().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // Send welcome email with invite link
        const emailResult = await sendWelcomeEmail({
          adminName: input.fullName,
          adminEmail: input.email,
          role: input.role,
          onboardingUrl: input.inviteUrl,
          supportEmail: 'support@playcoinkrazy.com',
          companyName: 'CoinKrazy',
        });

        // Log activity
        await logActivity({
          adminId: ctx.user.id,
          action: 'INVITE_EMAIL_SENT',
          resourceType: 'admin_invite',
          resourceId: input.email,
          details: {
            recipientEmail: input.email,
            recipientRole: input.role,
            status: emailResult ? 'success' : 'failed',
          },
        });

        return { success: emailResult };
      } catch (error) {
        console.error('[AdminInvites] Error sending invite email:', error);
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to send invite email',
        });
      }
    }),

  /**
   * Resend invite to admin
   */
  resendInvite: adminProcedure
    .input(
      z.object({
        email: z.string().email(),
        inviteUrl: z.string().url(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // Log activity
        await logActivity({
          adminId: ctx.user.id,
          action: 'INVITE_RESENT',
          resourceType: 'admin_invite',
          resourceId: input.email,
          details: {
            recipientEmail: input.email,
          },
        });

        // Emit alert
        await emitAlert({
          type: 'admin_invited',
          title: 'Admin Invite Resent',
          message: `Invitation resent to ${input.email}`,
          severity: 'info',
          resourceType: 'admin_invite',
          resourceId: input.email,
        });

        return { success: true };
      } catch (error) {
        console.error('[AdminInvites] Error resending invite:', error);
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to resend invite',
        });
      }
    }),

  /**
   * Get pending invites
   */
  getPendingInvites: adminProcedure.query(async ({ ctx }) => {
    try {
      // This would query the database for pending invites
      // For now, returning empty array as placeholder
      return {
        invites: [],
        total: 0,
      };
    } catch (error) {
      console.error('[AdminInvites] Error fetching pending invites:', error);
      throw new TRPCError({
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Failed to fetch pending invites',
      });
    }
  }),

  /**
   * Cancel invite
   */
  cancelInvite: adminProcedure
    .input(
      z.object({
        email: z.string().email(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // Log activity
        await logActivity({
          adminId: ctx.user.id,
          action: 'INVITE_CANCELLED',
          resourceType: 'admin_invite',
          resourceId: input.email,
          details: {
            cancelledEmail: input.email,
          },
        });

        // Emit alert
        await emitAlert({
          type: 'admin_invited',
          title: 'Admin Invite Cancelled',
          message: `Invitation cancelled for ${input.email}`,
          severity: 'warning',
          resourceType: 'admin_invite',
          resourceId: input.email,
        });

        return { success: true };
      } catch (error) {
        console.error('[AdminInvites] Error cancelling invite:', error);
        throw new TRPCError({
          code: 'INTERNAL_SERVER_ERROR',
          message: 'Failed to cancel invite',
        });
      }
    }),

  /**
   * Get invite status
   */
  getInviteStatus: protectedProcedure
    .input(z.object({ token: z.string() }))
    .query(async ({ input }) => {
      try {
        // Decode token and check validity
        const decodedToken = Buffer.from(input.token, 'base64').toString('utf-8');
        const [email, timestamp] = decodedToken.split(':');

        const inviteAge = Date.now() - parseInt(timestamp);
        const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;

        return {
          valid: inviteAge < sevenDaysMs,
          email,
          expiresAt: new Date(parseInt(timestamp) + sevenDaysMs).toISOString(),
          daysRemaining: Math.ceil((sevenDaysMs - inviteAge) / (24 * 60 * 60 * 1000)),
        };
      } catch (error) {
        console.error('[AdminInvites] Error checking invite status:', error);
        return {
          valid: false,
          email: null,
          expiresAt: null,
          daysRemaining: 0,
        };
      }
    }),
});
