import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
import { sign } from 'hono/jwt';
import bcrypt from 'bcryptjs';
import { nanoid } from 'nanoid';
import { prisma } from '../utils/prisma';
import { config } from '../config';

const authRoutes = new Hono();

// Validation schemas
const registerSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
  name: z.string().optional(),
  company: z.string().optional(),
});

const loginSchema = z.object({
  email: z.string().email(),
  password: z.string(),
});

// Register
authRoutes.post('/register', zValidator('json', registerSchema), async (c) => {
  const { email, password, name, company } = c.req.valid('json');
  
  // Check if user exists
  const existingUser = await prisma.user.findUnique({
    where: { email },
  });
  
  if (existingUser) {
    return c.json({ error: 'User already exists' }, 400);
  }
  
  // Hash password
  const passwordHash = await bcrypt.hash(password, 10);
  
  // Create user with API key
  const user = await prisma.user.create({
    data: {
      email,
      passwordHash,
      name,
      company,
      apiKey: `wcag_${nanoid(32)}`,
    },
    select: {
      id: true,
      email: true,
      name: true,
      company: true,
      apiKey: true,
      role: true,
    },
  });
  
  // Generate JWT
  const token = await sign(
    { 
      sub: user.id, 
      email: user.email,
      role: user.role,
    },
    config.JWT_SECRET,
    'HS256'
  );
  
  return c.json({
    user,
    token,
  });
});

// Login
authRoutes.post('/login', zValidator('json', loginSchema), async (c) => {
  const { email, password } = c.req.valid('json');
  
  // Find user
  const user = await prisma.user.findUnique({
    where: { email },
    select: {
      id: true,
      email: true,
      passwordHash: true,
      name: true,
      company: true,
      apiKey: true,
      role: true,
      isActive: true,
    },
  });
  
  if (!user || !user.isActive) {
    return c.json({ error: 'Invalid credentials' }, 401);
  }
  
  // Verify password
  const validPassword = await bcrypt.compare(password, user.passwordHash);
  if (!validPassword) {
    return c.json({ error: 'Invalid credentials' }, 401);
  }
  
  // Generate JWT
  const token = await sign(
    { 
      sub: user.id, 
      email: user.email,
      role: user.role,
    },
    config.JWT_SECRET,
    'HS256'
  );
  
  // Remove passwordHash from response
  const { passwordHash, ...userWithoutPassword } = user;
  
  return c.json({
    user: userWithoutPassword,
    token,
  });
});

// Refresh API key
authRoutes.post('/refresh-api-key', async (c) => {
  const userId = c.get('userId');
  
  if (!userId) {
    return c.json({ error: 'Unauthorized' }, 401);
  }
  
  const newApiKey = `wcag_${nanoid(32)}`;
  
  const user = await prisma.user.update({
    where: { id: userId },
    data: { apiKey: newApiKey },
    select: {
      id: true,
      email: true,
      apiKey: true,
    },
  });
  
  return c.json({ apiKey: user.apiKey });
});

// Get current user
authRoutes.get('/me', async (c) => {
  const userId = c.get('userId');
  
  if (!userId) {
    return c.json({ error: 'Unauthorized' }, 401);
  }
  
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: {
      id: true,
      email: true,
      name: true,
      company: true,
      role: true,
      apiKey: true,
      createdAt: true,
    },
  });
  
  if (!user) {
    return c.json({ error: 'User not found' }, 404);
  }
  
  return c.json(user);
});

export { authRoutes };