/**
 * Admin Authentication Routes
 */

import { Router, Request, Response } from 'express';
import { PrismaClient } from '@prisma/client';
import { z } from 'zod';
import jwt, { SignOptions } from 'jsonwebtoken';
import { verifyPassword } from '../../utils/encryption';
import { config } from '../../config';
import { logger } from '../../utils/logger';
import { validate } from '../../middleware/validator';

const router = Router();
const prisma = new PrismaClient();

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

const refreshSchema = z.object({
  refreshToken: z.string(),
});

/**
 * POST /v1/admin/auth/login
 * Admin login
 */
router.post('/login', validate(loginSchema), async (req: Request, res: Response) => {
  try {
    const { email, password } = req.body;

    const admin = await prisma.adminUser.findUnique({
      where: { email },
    });

    if (!admin) {
      return res.status(401).json({
        error: {
          code: 'INVALID_CREDENTIALS',
          message: 'Invalid email or password',
        },
      });
    }

    logger.debug('Admin found', {
      id: admin.id,
      email: admin.email,
      hasPasswordHash: !!(admin as any).password_hash,
      passwordHashLength: (admin as any).password_hash?.length,
    });

    const isValid = await verifyPassword(password, (admin as any).password_hash);

    if (!isValid) {
      return res.status(401).json({
        error: {
          code: 'INVALID_CREDENTIALS',
          message: 'Invalid email or password',
        },
      });
    }

    if (!(admin as any).is_active) {
      return res.status(403).json({
        error: {
          code: 'ADMIN_SUSPENDED',
          message: 'Admin account is suspended',
        },
      });
    }

    // Generate JWT tokens with admin-specific payload
    const accessOptions: SignOptions = {
      expiresIn: config.jwtAccessExpiry as any,
      issuer: 'translate.press.zone',
      audience: 'admin',
    };
    const accessToken = jwt.sign(
      {
        adminId: admin.id,
        email: admin.email,
        role: admin.role,
        type: 'admin_access',
      },
      config.jwtAdminSecret,
      accessOptions
    );

    const refreshOptions: SignOptions = {
      expiresIn: config.jwtRefreshExpiry as any,
      issuer: 'translate.press.zone',
      audience: 'admin',
    };
    const refreshToken = jwt.sign(
      {
        adminId: admin.id,
        type: 'admin_refresh',
      },
      config.jwtRefreshSecret,
      refreshOptions
    );

    await prisma.adminUser.update({
      where: { id: admin.id },
      data: { last_login_at: new Date() },
    });

    logger.info('Admin logged in', { adminId: admin.id, email: admin.email });

    return res.json({
      access_token: accessToken,
      refresh_token: refreshToken,
      user: {
        id: admin.id,
        email: admin.email,
        role: admin.role,
        created_at: (admin as any).created_at.toISOString(),
      },
    });
  } catch (error) {
    logger.error('Admin login error', {
      error: error instanceof Error ? {
        message: error.message,
        stack: error.stack,
      } : error
    });
    return res.status(500).json({
      error: {
        code: 'LOGIN_FAILED',
        message: 'An internal error occurred. Please try again later.',
      },
    });
  }
});

/**
 * POST /v1/admin/auth/refresh
 * Refresh admin token
 */
router.post('/refresh', validate(refreshSchema), async (req: Request, res: Response) => {
  try {
    const { refreshToken } = req.body;

    // Verify refresh token
    let payload: { adminId: string; type: string };
    try {
      payload = jwt.verify(refreshToken, config.jwtRefreshSecret, {
        issuer: 'translate.press.zone',
        audience: 'admin',
      }) as { adminId: string; type: string };

      if (payload.type !== 'admin_refresh') {
        throw new Error('Invalid token type');
      }
    } catch (error) {
      if (error instanceof jwt.TokenExpiredError) {
        return res.status(401).json({
          error: {
            code: 'TOKEN_EXPIRED',
            message: 'Refresh token expired',
          },
        });
      }
      throw error;
    }

    // Get admin user
    const admin = await prisma.adminUser.findUnique({
      where: { id: payload.adminId },
    });

    if (!admin || !(admin as any).is_active) {
      return res.status(401).json({
        error: {
          code: 'INVALID_TOKEN',
          message: 'Invalid or expired token',
        },
      });
    }

    // Generate new access token
    const tokenOptions: SignOptions = {
      expiresIn: config.jwtAccessExpiry as any,
      issuer: 'translate.press.zone',
      audience: 'admin',
    };
    const newAccessToken = jwt.sign(
      {
        adminId: admin.id,
        email: admin.email,
        role: admin.role,
        type: 'admin_access',
      },
      config.jwtAdminSecret,
      tokenOptions
    );

    return res.json({
      access_token: newAccessToken,
    });
  } catch (error: any) {
    logger.error('Token refresh error', { error });
    return res.status(500).json({
      error: {
        code: 'REFRESH_FAILED',
        message: 'Failed to refresh token',
      },
    });
  }
});

export default router;
