import { Router } from 'express';
import { UserController } from '../controllers/UserController';
import { AvailabilityController } from '../controllers/AvailabilityController';
import { EventTypeController } from '../controllers/EventTypeController';
import { BookingController } from '../controllers/BookingController';
import { CalendarController } from '../controllers/CalendarController';
import { EmbedController } from '../controllers/EmbedController';
import { ApiKeyController } from '../controllers/ApiKeyController';
import { LocationController } from '../controllers/LocationController';
import { requireAuth, requireScope } from '../middleware/auth.middleware';
import { validate, validateQuery } from '../middleware/validate.middleware';
import { updateProfileSchema } from '../dto/auth.dto';
import {
  enhanceProfileSchema,
  fetchLinkedInProfileSchema,
  importLinkedInProfileSchema,
} from '../dto/profile.dto';
import { updateAvailabilitySchema, copyAvailabilitySchema } from '../dto/availability.dto';
import { createEventTypeSchema, updateEventTypeSchema } from '../dto/eventType.dto';
import { hostCancelSchema, rescheduleSchema } from '../dto/booking.dto';
import {
  appleConnectSchema,
  updateCalendarConfigSchema,
  calendarEventsQuerySchema,
} from '../dto/calendar.dto';
import {
  createEmbedConfigSchema,
  updateEmbedConfigSchema,
  updateEventTypeEmbedSchema,
} from '../dto/embed.dto';
import { createApiKeySchema } from '../dto/apiKey.dto';
import { createLocationSchema, updateLocationSchema } from '../dto/location.dto';
import {
  testEmailSettingsSchema,
  updateEmailSettingsSchema,
  updateMeetingOutcomeSchema,
} from '../dto/communication.dto';
import { apiRateLimit } from '../middleware/rateLimit.middleware';
import { EmailSettingsController } from '../controllers/EmailSettingsController';
import { ProfileController } from '../controllers/ProfileController';

const router = Router();
const userController = new UserController();
const availabilityController = new AvailabilityController();
const eventTypeController = new EventTypeController();
const bookingController = new BookingController();
const calendarController = new CalendarController();
const embedController = new EmbedController();
const apiKeyController = new ApiKeyController();
const locationController = new LocationController();
const emailSettingsController = new EmailSettingsController();
const profileController = new ProfileController();

router.use(requireAuth);
router.use(apiRateLimit);

router.get('/', userController.getMe);
router.patch('/', validate(updateProfileSchema), userController.updateMe);

router.post('/profile/enhance', validate(enhanceProfileSchema), profileController.enhance);
router.post(
  '/profile/fetch-linkedin',
  validate(fetchLinkedInProfileSchema),
  profileController.fetchLinkedIn,
);
router.post(
  '/profile/import-linkedin',
  validate(importLinkedInProfileSchema),
  profileController.importLinkedIn,
);

router.get('/event-types', eventTypeController.list);
router.post('/event-types', validate(createEventTypeSchema), eventTypeController.create);
router.patch('/event-types/:id', validate(updateEventTypeSchema), eventTypeController.update);
router.delete('/event-types/:id', eventTypeController.delete);

router.get('/event-types/:id/availability', availabilityController.getForEventType);
router.put(
  '/event-types/:id/availability',
  validate(updateAvailabilitySchema),
  availabilityController.updateForEventType,
);
router.post(
  '/event-types/:id/availability/copy-from',
  validate(copyAvailabilitySchema),
  availabilityController.copyForEventType,
);

router.get('/event-types/:id/embed', embedController.getForEventType);
router.put(
  '/event-types/:id/embed',
  validate(updateEventTypeEmbedSchema),
  embedController.updateForEventType,
);

router.get('/bookings', requireScope('bookings:read'), bookingController.list);
router.post(
  '/bookings/:id/cancel',
  validate(hostCancelSchema),
  bookingController.cancel,
);
router.post(
  '/bookings/:id/reschedule',
  validate(rescheduleSchema),
  bookingController.reschedule,
);
router.patch(
  '/bookings/:id/outcome',
  validate(updateMeetingOutcomeSchema),
  bookingController.updateOutcome,
);

router.get('/email-settings', emailSettingsController.get);
router.put('/email-settings', validate(updateEmailSettingsSchema), emailSettingsController.update);
router.post('/email-settings/test', validate(testEmailSettingsSchema), emailSettingsController.sendTest);

router.get('/calendar-connections', calendarController.list);
router.get('/calendar-connections/oauth/:provider/authorize', calendarController.authorize);
router.post('/calendar-connections/apple', validate(appleConnectSchema), calendarController.connectApple);
router.patch('/calendar-connections/:id', validate(updateCalendarConfigSchema), calendarController.updateConfig);
router.post('/calendar-connections/:id/sync', calendarController.sync);
router.get(
  '/calendar-connections/:id/events',
  validateQuery(calendarEventsQuerySchema),
  calendarController.listEvents,
);
router.delete('/calendar-connections/:id', calendarController.disconnect);

router.get('/embed-configs', embedController.list);
router.post('/embed-configs', validate(createEmbedConfigSchema), embedController.create);
router.patch('/embed-configs/:id', validate(updateEmbedConfigSchema), embedController.update);
router.delete('/embed-configs/:id', embedController.delete);

router.get('/api-keys', apiKeyController.list);
router.post('/api-keys', validate(createApiKeySchema), apiKeyController.create);
router.delete('/api-keys/:id', apiKeyController.revoke);

router.get('/locations', locationController.list);
router.post('/locations', validate(createLocationSchema), locationController.create);
router.patch('/locations/:id', validate(updateLocationSchema), locationController.update);
router.delete('/locations/:id', locationController.delete);

export default router;
