import { McpServer } from '@modelcontextprotocol/sdk/server/mcp';
import { z } from 'zod';
import { isDemoUser } from '../../services/authService';
import {
  markCountryVisited, unmarkCountryVisited, createBucketItem, deleteBucketItem,
  getStats as getAtlasStats, listManuallyVisitedRegions,
  markRegionVisited, unmarkRegionVisited, getCountryPlaces, updateBucketItem,
} from '../../services/atlasService';
import { isAddonEnabled } from '../../services/adminService';
import { ADDON_IDS } from '../../addons';
import {
  TOOL_ANNOTATIONS_WRITE, TOOL_ANNOTATIONS_DELETE, TOOL_ANNOTATIONS_NON_IDEMPOTENT,
  TOOL_ANNOTATIONS_READONLY,
  demoDenied, ok,
} from './_shared';
import { canRead, canWrite } from '../scopes';

export function registerAtlasTools(server: McpServer, userId: number, scopes: string[] | null): void {
  const R = canRead(scopes, 'atlas');
  const W = canWrite(scopes, 'atlas');

  if (!isAddonEnabled(ADDON_IDS.ATLAS)) return;

  // --- BUCKET LIST ---

  if (W) server.registerTool(
    'create_bucket_list_item',
    {
      description: 'Add a destination to your personal travel bucket list.',
      inputSchema: {
        name: z.string().min(1).max(200).describe('Destination or experience name'),
        lat: z.number().optional(),
        lng: z.number().optional(),
        country_code: z.string().length(2).toUpperCase().optional().describe('ISO 3166-1 alpha-2 country code'),
        notes: z.string().max(1000).optional(),
      },
      annotations: TOOL_ANNOTATIONS_NON_IDEMPOTENT,
    },
    async ({ name, lat, lng, country_code, notes }) => {
      if (isDemoUser(userId)) return demoDenied();
      const item = createBucketItem(userId, { name, lat, lng, country_code, notes });
      return ok({ item });
    }
  );

  if (W) server.registerTool(
    'delete_bucket_list_item',
    {
      description: 'Remove an item from your travel bucket list.',
      inputSchema: {
        itemId: z.number().int().positive(),
      },
      annotations: TOOL_ANNOTATIONS_DELETE,
    },
    async ({ itemId }) => {
      if (isDemoUser(userId)) return demoDenied();
      const deleted = deleteBucketItem(userId, itemId);
      if (!deleted) return { content: [{ type: 'text' as const, text: 'Bucket list item not found.' }], isError: true };
      return ok({ success: true });
    }
  );

  // --- ATLAS ---

  if (W) server.registerTool(
    'mark_country_visited',
    {
      description: 'Mark a country as visited in your Atlas.',
      inputSchema: {
        country_code: z.string().length(2).toUpperCase().describe('ISO 3166-1 alpha-2 country code (e.g. "FR", "JP")'),
      },
      annotations: TOOL_ANNOTATIONS_NON_IDEMPOTENT,
    },
    async ({ country_code }) => {
      if (isDemoUser(userId)) return demoDenied();
      markCountryVisited(userId, country_code.toUpperCase());
      return ok({ success: true, country_code: country_code.toUpperCase() });
    }
  );

  if (W) server.registerTool(
    'unmark_country_visited',
    {
      description: 'Remove a country from your visited countries in Atlas.',
      inputSchema: {
        country_code: z.string().length(2).toUpperCase().describe('ISO 3166-1 alpha-2 country code'),
      },
      annotations: TOOL_ANNOTATIONS_DELETE,
    },
    async ({ country_code }) => {
      if (isDemoUser(userId)) return demoDenied();
      unmarkCountryVisited(userId, country_code.toUpperCase());
      return ok({ success: true, country_code: country_code.toUpperCase() });
    }
  );

  // --- ATLAS EXPANDED ---

  if (R) server.registerTool(
      'get_atlas_stats',
      {
        description: 'Get atlas statistics — total visited countries, region counts, continent breakdown.',
        inputSchema: {},
        annotations: TOOL_ANNOTATIONS_READONLY,
      },
      async () => {
        const stats = await getAtlasStats(userId);
        return ok({ stats });
      }
    );

    if (R) server.registerTool(
      'list_visited_regions',
      {
        description: 'List all manually visited sub-country regions for the current user.',
        inputSchema: {},
        annotations: TOOL_ANNOTATIONS_READONLY,
      },
      async () => {
        const regions = listManuallyVisitedRegions(userId);
        return ok({ regions });
      }
    );

    if (W) server.registerTool(
      'mark_region_visited',
      {
        description: 'Mark a sub-country region as visited.',
        inputSchema: {
          regionCode: z.string().describe('ISO region code e.g. US-CA'),
          regionName: z.string(),
          countryCode: z.string().describe('ISO 3166-1 alpha-2 country code'),
        },
        annotations: TOOL_ANNOTATIONS_NON_IDEMPOTENT,
      },
      async ({ regionCode, regionName, countryCode }) => {
        if (isDemoUser(userId)) return demoDenied();
        markRegionVisited(userId, regionCode, regionName, countryCode);
        const region = listManuallyVisitedRegions(userId).find(r => r.region_code === regionCode);
        return ok({ region });
      }
    );

    if (W) server.registerTool(
      'unmark_region_visited',
      {
        description: 'Remove a region from the visited list.',
        inputSchema: {
          regionCode: z.string(),
        },
        annotations: TOOL_ANNOTATIONS_DELETE,
      },
      async ({ regionCode }) => {
        if (isDemoUser(userId)) return demoDenied();
        unmarkRegionVisited(userId, regionCode);
        return ok({ success: true });
      }
    );

    if (R) server.registerTool(
      'get_country_atlas_places',
      {
        description: 'Get places saved in the user\'s atlas for a specific country.',
        inputSchema: {
          countryCode: z.string().describe('ISO 3166-1 alpha-2 country code'),
        },
        annotations: TOOL_ANNOTATIONS_READONLY,
      },
      async ({ countryCode }) => {
        const result = getCountryPlaces(userId, countryCode);
        return ok(result);
      }
    );

    if (W) server.registerTool(
      'update_bucket_list_item',
      {
        description: 'Update a bucket list item (notes, name, target date, location).',
        inputSchema: {
          itemId: z.number().int().positive(),
          name: z.string().optional(),
          notes: z.string().optional(),
          lat: z.number().nullable().optional(),
          lng: z.number().nullable().optional(),
          country_code: z.string().optional(),
          target_date: z.string().nullable().optional(),
        },
        annotations: TOOL_ANNOTATIONS_WRITE,
      },
      async ({ itemId, name, notes, lat, lng, country_code, target_date }) => {
        if (isDemoUser(userId)) return demoDenied();
        const item = updateBucketItem(userId, itemId, { name, notes, lat, lng, country_code, target_date });
        if (!item) return { content: [{ type: 'text' as const, text: 'Bucket list item not found.' }], isError: true };
        return ok({ item });
      }
    );
}
