import fp from 'fastify-plugin';
import { asClass, Lifetime } from 'awilix';
import type { ZodTypeProvider } from 'fastify-type-provider-zod';
import { UserResponseSchema } from '@meshitrack/shared';
import { UsersRepository } from './users.repository.js';
import { UsersService } from './users.service.js';
import { NotFoundError } from '../../common/errors.js';

type AnyUserDoc = {
  _id: string | { toString: () => string };
  keycloakId: string;
  displayName: string;
  email: string;
  householdIds: string[];
  defaultHouseholdId?: string | null;
  createdAt: string | { toISOString: () => string };
  updatedAt: string | { toISOString: () => string };
};

function toUserResponse(doc: AnyUserDoc) {
  const id = typeof doc._id === 'string' ? doc._id : doc._id.toString();
  const createdAt = typeof doc.createdAt === 'string' ? doc.createdAt : doc.createdAt.toISOString();
  const updatedAt = typeof doc.updatedAt === 'string' ? doc.updatedAt : doc.updatedAt.toISOString();
  return {
    _id: id,
    keycloakId: doc.keycloakId,
    displayName: doc.displayName,
    email: doc.email,
    householdIds: doc.householdIds,
    defaultHouseholdId: doc.defaultHouseholdId ?? null,
    createdAt,
    updatedAt,
  };
}

declare module '@fastify/awilix' {
  interface Cradle {
    usersRepository: UsersRepository;
    usersService: UsersService;
  }
}

export default fp(
  async (fastify) => {
    // Register DI
    fastify.diContainer.register({
      usersRepository: asClass(UsersRepository, { lifetime: Lifetime.SINGLETON }),
      usersService: asClass(UsersService, { lifetime: Lifetime.SINGLETON }),
    });

    const app = fastify.withTypeProvider<ZodTypeProvider>();

    // GET /api/v1/users/me — get current user profile (syncs from token on first call)
    app.route({
      method: 'GET',
      url: '/api/v1/users/me',
      config: { skipHousehold: true },
      schema: {
        response: { 200: UserResponseSchema },
      },
      handler: async (request, reply) => {
        const service = fastify.diContainer.resolve('usersService');
        const user = await service.syncFromToken(request.user);
        if (!user) throw new NotFoundError('User sync failed');
        return reply.send(toUserResponse(user));
      },
    });
  },
  { name: 'users-routes', dependencies: ['auth-plugin'] },
);
