import { Request, Response, NextFunction } from 'express';
import { BookingService } from '../services/BookingService';
import { UserRepository } from '../models/repositories/UserRepository';
import { BookingView } from '../views/BookingView';
import { AppError } from '../utils/AppError';

export class HostByIdController {
  constructor(
    private bookingService = new BookingService(),
    private userRepo = new UserRepository(),
  ) {}

  /**
   * Create appointment if startTime is free → 201 { created: true, booking }.
   * If taken / not available → 200 { created: false, availableTimes }
   * (200 so voice-agent tools can Jinja-read alternatives; HTTP 409 hides the body).
   */
  createBooking = async (req: Request, res: Response, next: NextFunction) => {
    try {
      const user = await this.userRepo.findById(req.params.userId);
      if (!user) throw new AppError('not_found', 404, 'User not found.');

      const idempotencyKey = req.headers['idempotency-key'] as string | undefined;
      const booking = await this.bookingService.createForHost(user.id, {
        ...req.body,
        idempotencyKey,
      });
      res.status(201).json({
        created: true,
        booking: BookingView.toHostList(booking),
      });
    } catch (err) {
      if (err instanceof AppError && err.code === 'slot_unavailable') {
        const details = (err.details ?? {}) as Record<string, unknown>;
        res.status(200).json({
          created: false,
          error: err.code,
          message: err.message,
          requestedStartTime: details.requestedStartTime,
          availableTimes: details.availableTimes ?? [],
          alternatives: details.alternatives ?? details.availableTimes ?? [],
          details,
        });
        return;
      }
      next(err);
    }
  };
}
