// src/server/features/auth/auth.routes.ts
// HTTP handlers for authentication routes

import { ZodTypeProvider } from 'fastify-type-provider-zod';
import { FastifyInstance } from 'fastify';
import {
  loginSchema,
  registerSchema,
  loginResponseSchema,
  registerResponseSchema,
  errorResponseSchema,
  logoutResponseSchema,
} from './auth.schema';
import { login, register } from './auth.service';
import { AuthorizationError, ACCOUNT_DISABLED_ERROR_CODE, isAccountAccessAllowed } from '../../shared/lib/auth';
import { db } from '../../shared/db/client';
import { employees } from '../personnel/db/employees.table';
import { eq } from 'drizzle-orm';

export const authRoutes = async (fastify: FastifyInstance) => {
  const server = fastify.withTypeProvider<ZodTypeProvider>();

  // POST /login - Authenticate user and set JWT token in HttpOnly cookie
  server.post('/login', {
    schema: {
      body: loginSchema,
      response: {
        200: loginResponseSchema,
        401: errorResponseSchema,
        403: errorResponseSchema,
      },
    },
  }, async (request: any, reply: any) => {
    const { username, password } = request.body;

    const result = await login({ username, password });

    // Get fresh user data from database to check account access
    const freshUserData = await db
      .select({
        id: employees.id,
        isFired: employees.isFired,
        createdAt: employees.createdAt,
        archivedAt: employees.archivedAt,
      })
      .from(employees)
      .where(eq(employees.id, result.user.id))
      .limit(1);

    if (!freshUserData || freshUserData.length === 0) {
      throw new AuthorizationError('Пользователь не найден', 403, ACCOUNT_DISABLED_ERROR_CODE);
    }

    const { isFired, createdAt, archivedAt } = freshUserData[0];

    // Check if account access is allowed
    // isFired may be null from DB, treat null as false (not fired)
    const accessAllowed = isAccountAccessAllowed({
      isFired: isFired ?? false,
      createdAt,
      archivedAt,
    });

    if (!accessAllowed) {
      // Determine appropriate error message based on the reason
      const { dayjs } = await import('../../shared/lib/dayjs');
      const mskNow = dayjs().tz('Europe/Moscow');
      const isFutureHire = mskNow.isBefore(dayjs.utc(createdAt).tz('Europe/Moscow').startOf('day'));
      const errorMessage = isFutureHire
        ? 'Учетная запись еще не активирована'
        : 'Срок действия учетной записи истек';

      throw new AuthorizationError(errorMessage, 403, ACCOUNT_DISABLED_ERROR_CODE);
    }

    // Generate JWT token
    const token = fastify.jwt.sign({
      id: result.user.id,
      username: result.user.username,
      role: result.user.role,
    });

    reply.setCookie('auth_token', token, {
      httpOnly: true,
      
      // 👇 ИЗМЕНИ ЭТИ ДВЕ СТРОКИ 👇
      secure: false,       // Ставим false, чтобы работало по HTTP (без сертификата)
      sameSite: 'lax',     // Меняем strict на lax, чтобы кука ходила между портами 5173 и 3000
      
      path: '/',
      maxAge: 60 * 60 * 24 * 7, // 7 days
    });

    reply.code(200).send({
      success: true,
      data: {
        user: {
          ...result.user,
          employeeId: result.user.id, // Map id to employeeId for frontend compatibility
        },
      },
    });
  });

  // POST /register - Register new user and employee
  server.post('/register', {
    schema: {
      body: registerSchema,
      response: {
        200: registerResponseSchema,
        400: errorResponseSchema,
      },
    },
  }, async (request: any, reply: any) => {
    const { username, password, email, name, position, phone } = request.body;

    const result = await register({ username, password, email, name, position, phone });
    reply.code(200).send({
      success: true,
      data: {
        user: {
          ...result,
          employeeId: result.id, // Map id to employeeId for frontend compatibility
        },
      },
    });
  });

  // POST /logout - Clear auth cookie
  server.post('/logout', {
    schema: {
      response: {
        200: logoutResponseSchema,
      },
    },
  }, async (request: any, reply: any) => {
    // Clear auth cookie by setting it with expired date
    reply.setCookie('auth_token', '', {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'strict',
      path: '/',
      expires: new Date(0), // Set to past date to expire immediately
    });

    reply.code(200).send({ success: true });
  });
};
