import crypto from "crypto";
import { getDb } from "../db.ts";
import { users } from "../../drizzle/schema.ts";
import { eq } from "drizzle-orm";

const PASSWORD_RESET_TOKEN_EXPIRY = 1 * 60 * 60 * 1000; // 1 hour
const PASSWORD_RESET_TOKEN_LENGTH = 32;

/**
 * Generate a password reset token
 */
export async function generatePasswordResetToken(email: string): Promise<string | null> {
  const db = getDb();
  const user = await db
    .select()
    .from(users)
    .where(eq(users.email, email))
    .limit(1)
    .then((rows) => rows[0]);

  if (!user) {
    return null;
  }

  const token = crypto.randomBytes(PASSWORD_RESET_TOKEN_LENGTH).toString("hex");
  const expiresAt = new Date(Date.now() + PASSWORD_RESET_TOKEN_EXPIRY);

  await db
    .update(users)
    .set({
      passwordResetToken: token,
      passwordResetTokenExpiresAt: expiresAt,
    })
    .where(eq(users.id, user.id));

  return token;
}

/**
 * Verify a password reset token
 */
export async function verifyPasswordResetToken(token: string): Promise<string | null> {
  const db = getDb();
  const user = await db
    .select()
    .from(users)
    .where(eq(users.passwordResetToken, token))
    .limit(1)
    .then((rows) => rows[0]);

  if (!user) {
    return null;
  }

  // Check if token has expired
  if (user.passwordResetTokenExpiresAt && user.passwordResetTokenExpiresAt < new Date()) {
    return null;
  }

  return user.id;
}

/**
 * Reset password with token
 */
export async function resetPasswordWithToken(token: string, newPasswordHash: string): Promise<boolean> {
  const userId = await verifyPasswordResetToken(token);
  if (!userId) {
    return false;
  }

  const db = getDb();
  await db
    .update(users)
    .set({
      passwordHash: newPasswordHash,
      passwordResetToken: null,
      passwordResetTokenExpiresAt: null,
    })
    .where(eq(users.id, userId));

  return true;
}

/**
 * Send password reset email (placeholder)
 */
export async function sendPasswordResetEmail(email: string, token: string, origin: string): Promise<boolean> {
  try {
    const resetUrl = `${origin}/reset-password?token=${token}`;

    console.log(`[Account Recovery] Sending password reset email to ${email}`);
    console.log(`[Account Recovery] Reset URL: ${resetUrl}`);

    // TODO: Implement actual email sending
    // await emailService.send({
    //   to: email,
    //   subject: "Reset your CoinKrazy password",
    //   html: `
    //     <h2>Password Reset Request</h2>
    //     <p>Click the link below to reset your password:</p>
    //     <a href="${resetUrl}">Reset Password</a>
    //     <p>This link expires in 1 hour.</p>
    //     <p>If you didn't request this, please ignore this email.</p>
    //   `
    // });

    return true;
  } catch (error) {
    console.error("[Account Recovery] Failed to send password reset email:", error);
    return false;
  }
}

/**
 * Store support ticket
 */
export interface SupportTicket {
  id?: string;
  userId?: string;
  email: string;
  subject: string;
  message: string;
  category: "account" | "payment" | "technical" | "other";
  status: "open" | "in_progress" | "resolved";
  createdAt?: Date;
  updatedAt?: Date;
}

// In-memory storage for support tickets (replace with database in production)
const supportTickets: Map<string, SupportTicket> = new Map();

/**
 * Create a support ticket
 */
export async function createSupportTicket(ticket: Omit<SupportTicket, "id" | "status" | "createdAt" | "updatedAt">): Promise<SupportTicket> {
  const id = crypto.randomUUID();
  const now = new Date();

  const newTicket: SupportTicket = {
    ...ticket,
    id,
    status: "open",
    createdAt: now,
    updatedAt: now,
  };

  supportTickets.set(id, newTicket);

  console.log(`[Support] New ticket created: ${id} from ${ticket.email}`);

  return newTicket;
}

/**
 * Get support ticket by ID
 */
export async function getSupportTicket(ticketId: string): Promise<SupportTicket | null> {
  return supportTickets.get(ticketId) || null;
}

/**
 * Get all support tickets for a user
 */
export async function getUserSupportTickets(userId: string): Promise<SupportTicket[]> {
  return Array.from(supportTickets.values()).filter((ticket) => ticket.userId === userId);
}

/**
 * Update support ticket status
 */
export async function updateSupportTicketStatus(ticketId: string, status: SupportTicket["status"]): Promise<boolean> {
  const ticket = supportTickets.get(ticketId);
  if (!ticket) {
    return false;
  }

  ticket.status = status;
  ticket.updatedAt = new Date();
  supportTickets.set(ticketId, ticket);

  return true;
}
