import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp';
import { canAccessTrip } from '../db/database';
import { listTrips, getTrip, getTripOwner, listMembers } from '../services/tripService';
import { listDays, listAccommodations } from '../services/dayService';
import { listPlaces } from '../services/placeService';
import { listBudgetItems } from '../services/budgetService';
import { listItems as listPackingItems } from '../services/packingService';
import { listReservations } from '../services/reservationService';
import { listNotes as listDayNotes } from '../services/dayNoteService';
import { listNotes as listCollabNotes } from '../services/collabService';
import { listCategories } from '../services/categoryService';
import { listBucketList, listVisitedCountries } from '../services/atlasService';

function parseId(value: string | string[]): number | null {
  const n = Number(Array.isArray(value) ? value[0] : value);
  return Number.isInteger(n) && n > 0 ? n : null;
}

function accessDenied(uri: string) {
  return {
    contents: [{
      uri,
      mimeType: 'application/json',
      text: JSON.stringify({ error: 'Trip not found or access denied' }),
    }],
  };
}

function jsonContent(uri: string, data: unknown) {
  return {
    contents: [{
      uri,
      mimeType: 'application/json',
      text: JSON.stringify(data, null, 2),
    }],
  };
}

export function registerResources(server: McpServer, userId: number): void {
  // List all accessible trips
  server.registerResource(
    'trips',
    'trek://trips',
    { description: 'All trips the user owns or is a member of' },
    async (uri) => {
      const trips = listTrips(userId, 0);
      return jsonContent(uri.href, trips);
    }
  );

  // Single trip detail
  server.registerResource(
    'trip',
    new ResourceTemplate('trek://trips/{tripId}', { list: undefined }),
    { description: 'A single trip with metadata and member count' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const trip = getTrip(id, userId);
      return jsonContent(uri.href, trip);
    }
  );

  // Days with assigned places
  server.registerResource(
    'trip-days',
    new ResourceTemplate('trek://trips/{tripId}/days', { list: undefined }),
    { description: 'Days of a trip with their assigned places' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);

      const { days } = listDays(id);
      return jsonContent(uri.href, days);
    }
  );

  // Places in a trip
  server.registerResource(
    'trip-places',
    new ResourceTemplate('trek://trips/{tripId}/places', { list: undefined }),
    { description: 'All places/POIs saved in a trip' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const places = listPlaces(String(id), {});
      return jsonContent(uri.href, places);
    }
  );

  // Budget items
  server.registerResource(
    'trip-budget',
    new ResourceTemplate('trek://trips/{tripId}/budget', { list: undefined }),
    { description: 'Budget and expense items for a trip' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const items = listBudgetItems(id);
      return jsonContent(uri.href, items);
    }
  );

  // Packing checklist
  server.registerResource(
    'trip-packing',
    new ResourceTemplate('trek://trips/{tripId}/packing', { list: undefined }),
    { description: 'Packing checklist for a trip' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const items = listPackingItems(id);
      return jsonContent(uri.href, items);
    }
  );

  // Reservations (flights, hotels, restaurants)
  server.registerResource(
    'trip-reservations',
    new ResourceTemplate('trek://trips/{tripId}/reservations', { list: undefined }),
    { description: 'Reservations (flights, hotels, restaurants) for a trip' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const reservations = listReservations(id);
      return jsonContent(uri.href, reservations);
    }
  );

  // Day notes
  server.registerResource(
    'day-notes',
    new ResourceTemplate('trek://trips/{tripId}/days/{dayId}/notes', { list: undefined }),
    { description: 'Notes for a specific day in a trip' },
    async (uri, { tripId, dayId }) => {
      const tId = parseId(tripId);
      const dId = parseId(dayId);
      if (tId === null || dId === null || !canAccessTrip(tId, userId)) return accessDenied(uri.href);
      const notes = listDayNotes(dId, tId);
      return jsonContent(uri.href, notes);
    }
  );

  // Accommodations (hotels, rentals) per trip
  server.registerResource(
    'trip-accommodations',
    new ResourceTemplate('trek://trips/{tripId}/accommodations', { list: undefined }),
    { description: 'Accommodations (hotels, rentals) for a trip with check-in/out details' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const accommodations = listAccommodations(id);
      return jsonContent(uri.href, accommodations);
    }
  );

  // Trip members (owner + collaborators)
  server.registerResource(
    'trip-members',
    new ResourceTemplate('trek://trips/{tripId}/members', { list: undefined }),
    { description: 'Owner and collaborators of a trip' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const ownerRow = getTripOwner(id);
      if (!ownerRow) return accessDenied(uri.href);
      const { owner, members } = listMembers(id, ownerRow.user_id);
      return jsonContent(uri.href, { owner, members });
    }
  );

  // Collab notes for a trip
  server.registerResource(
    'trip-collab-notes',
    new ResourceTemplate('trek://trips/{tripId}/collab-notes', { list: undefined }),
    { description: 'Shared collaborative notes for a trip' },
    async (uri, { tripId }) => {
      const id = parseId(tripId);
      if (id === null || !canAccessTrip(id, userId)) return accessDenied(uri.href);
      const notes = listCollabNotes(id);
      return jsonContent(uri.href, notes);
    }
  );

  // All place categories (global, no trip filter)
  server.registerResource(
    'categories',
    'trek://categories',
    { description: 'All available place categories (id, name, color, icon) for use when creating places' },
    async (uri) => {
      const categories = listCategories();
      return jsonContent(uri.href, categories);
    }
  );

  // User's bucket list
  server.registerResource(
    'bucket-list',
    'trek://bucket-list',
    { description: 'Your personal travel bucket list' },
    async (uri) => {
      const items = listBucketList(userId);
      return jsonContent(uri.href, items);
    }
  );

  // User's visited countries
  server.registerResource(
    'visited-countries',
    'trek://visited-countries',
    { description: 'Countries you have marked as visited in Atlas' },
    async (uri) => {
      const countries = listVisitedCountries(userId);
      return jsonContent(uri.href, countries);
    }
  );
}
