import { FastifyReply, FastifyRequest } from 'fastify';
import { OwnershipCostsService } from '../domain/ownership-costs.service';
import type { CreateBody, UpdateBody, IdParams, ListQuery } from './ownership-costs.validation';
import { logger } from '../../../core/logging/logger';

export class OwnershipCostsController {
  private readonly service = new OwnershipCostsService();

  async list(request: FastifyRequest<{ Querystring: ListQuery }>, reply: FastifyReply) {
    const userId = (request as any).user?.sub as string;

    logger.info('Ownership costs list requested', {
      operation: 'ownership-costs.list',
      userId,
      filters: {
        vehicleId: request.query.vehicleId,
        costType: request.query.costType,
        documentId: request.query.documentId,
      },
    });

    const costs = await this.service.getCosts(userId, {
      vehicleId: request.query.vehicleId,
      costType: request.query.costType,
      documentId: request.query.documentId,
    });

    logger.info('Ownership costs list retrieved', {
      operation: 'ownership-costs.list.success',
      userId,
      costCount: costs.length,
    });

    return reply.code(200).send(costs);
  }

  async get(request: FastifyRequest<{ Params: IdParams }>, reply: FastifyReply) {
    const userId = (request as any).user?.sub as string;
    const costId = request.params.id;

    logger.info('Ownership cost get requested', {
      operation: 'ownership-costs.get',
      userId,
      costId,
    });

    const cost = await this.service.getCost(userId, costId);
    if (!cost) {
      logger.warn('Ownership cost not found', {
        operation: 'ownership-costs.get.not_found',
        userId,
        costId,
      });
      return reply.code(404).send({ error: 'Not Found' });
    }

    logger.info('Ownership cost retrieved', {
      operation: 'ownership-costs.get.success',
      userId,
      costId,
      vehicleId: cost.vehicleId,
      costType: cost.costType,
    });

    return reply.code(200).send(cost);
  }

  async create(request: FastifyRequest<{ Body: CreateBody }>, reply: FastifyReply) {
    const userId = (request as any).user?.sub as string;

    logger.info('Ownership cost create requested', {
      operation: 'ownership-costs.create',
      userId,
      vehicleId: request.body.vehicleId,
      costType: request.body.costType,
      amount: request.body.amount,
    });

    const created = await this.service.createCost(userId, request.body);

    logger.info('Ownership cost created', {
      operation: 'ownership-costs.create.success',
      userId,
      costId: created.id,
      vehicleId: created.vehicleId,
      costType: created.costType,
      amount: created.amount,
    });

    return reply.code(201).send(created);
  }

  async update(request: FastifyRequest<{ Params: IdParams; Body: UpdateBody }>, reply: FastifyReply) {
    const userId = (request as any).user?.sub as string;
    const costId = request.params.id;

    logger.info('Ownership cost update requested', {
      operation: 'ownership-costs.update',
      userId,
      costId,
      updateFields: Object.keys(request.body),
    });

    const updated = await this.service.updateCost(userId, costId, request.body);
    if (!updated) {
      logger.warn('Ownership cost not found for update', {
        operation: 'ownership-costs.update.not_found',
        userId,
        costId,
      });
      return reply.code(404).send({ error: 'Not Found' });
    }

    logger.info('Ownership cost updated', {
      operation: 'ownership-costs.update.success',
      userId,
      costId,
      vehicleId: updated.vehicleId,
      costType: updated.costType,
    });

    return reply.code(200).send(updated);
  }

  async remove(request: FastifyRequest<{ Params: IdParams }>, reply: FastifyReply) {
    const userId = (request as any).user?.sub as string;
    const costId = request.params.id;

    logger.info('Ownership cost delete requested', {
      operation: 'ownership-costs.delete',
      userId,
      costId,
    });

    await this.service.deleteCost(userId, costId);

    logger.info('Ownership cost deleted', {
      operation: 'ownership-costs.delete.success',
      userId,
      costId,
    });

    return reply.code(204).send();
  }
}
