import type { BigCommerceClient } from '../clients/bigcommerce.js';
import type { Category, Brand } from '../types/index.js';

export function registerCatalogTools(client: BigCommerceClient) {
  return {
    // Categories
    bigcommerce_list_categories: {
      description: 'List all product categories',
      parameters: {
        type: 'object' as const,
        properties: {
          parent_id: { type: 'number', description: 'Filter by parent category ID' },
          name: { type: 'string', description: 'Filter by category name (partial match)' },
          is_visible: { type: 'boolean', description: 'Filter by visibility' },
          page: { type: 'number', description: 'Page number (default: 1)' },
          limit: { type: 'number', description: 'Items per page (default: 50, max: 250)' },
        },
      },
      handler: async (params: Record<string, unknown>) => {
        const queryParams: Record<string, string | number> = {};
        if (params.parent_id !== undefined) queryParams.parent_id = params.parent_id as number;
        if (params.name) queryParams['name:like'] = params.name as string;
        if (params.is_visible !== undefined) queryParams.is_visible = params.is_visible ? 'true' : 'false';

        const page = (params.page as number) || 1;
        const limit = (params.limit as number) || 50;

        const result = await client.getPage<Category>('/catalog/categories', page, limit, queryParams);
        return { categories: result.data, meta: result.meta };
      },
    },

    bigcommerce_get_category: {
      description: 'Get a single category by ID',
      parameters: {
        type: 'object' as const,
        properties: {
          category_id: { type: 'number', description: 'Category ID', required: true },
        },
        required: ['category_id'],
      },
      handler: async (params: { category_id: number }) => {
        const result = await client.get<{ data: Category }>(`/catalog/categories/${params.category_id}`);
        return result.data;
      },
    },

    bigcommerce_create_category: {
      description: 'Create a new product category',
      parameters: {
        type: 'object' as const,
        properties: {
          name: { type: 'string', description: 'Category name', required: true },
          parent_id: { type: 'number', description: 'Parent category ID (0 for root category)', required: true },
          description: { type: 'string', description: 'Category description' },
          sort_order: { type: 'number', description: 'Sort order' },
          is_visible: { type: 'boolean', description: 'Visibility (default: true)' },
          page_title: { type: 'string', description: 'SEO page title' },
          meta_description: { type: 'string', description: 'SEO meta description' },
          meta_keywords: { type: 'array', items: { type: 'string' }, description: 'SEO meta keywords' },
          image_url: { type: 'string', description: 'Category image URL' },
        },
        required: ['name', 'parent_id'],
      },
      handler: async (params: Partial<Category>) => {
        const result = await client.post<{ data: Category }>('/catalog/categories', params);
        return result.data;
      },
    },

    bigcommerce_update_category: {
      description: 'Update an existing category',
      parameters: {
        type: 'object' as const,
        properties: {
          category_id: { type: 'number', description: 'Category ID', required: true },
          name: { type: 'string', description: 'Category name' },
          parent_id: { type: 'number', description: 'Parent category ID' },
          description: { type: 'string', description: 'Category description' },
          sort_order: { type: 'number', description: 'Sort order' },
          is_visible: { type: 'boolean', description: 'Visibility' },
          page_title: { type: 'string', description: 'SEO page title' },
        },
        required: ['category_id'],
      },
      handler: async (params: { category_id: number; [key: string]: unknown }) => {
        const { category_id, ...updateData } = params;
        const result = await client.put<{ data: Category }>(`/catalog/categories/${category_id}`, updateData);
        return result.data;
      },
    },

    bigcommerce_delete_category: {
      description: 'Delete a category',
      parameters: {
        type: 'object' as const,
        properties: {
          category_id: { type: 'number', description: 'Category ID', required: true },
        },
        required: ['category_id'],
      },
      handler: async (params: { category_id: number }) => {
        await client.delete(`/catalog/categories/${params.category_id}`);
        return { success: true, message: `Category ${params.category_id} deleted` };
      },
    },

    bigcommerce_get_category_tree: {
      description: 'Get the full category tree structure',
      parameters: {
        type: 'object' as const,
        properties: {},
      },
      handler: async () => {
        const result = await client.get<{ data: Category[] }>('/catalog/categories/tree');
        return result.data;
      },
    },

    // Brands
    bigcommerce_list_brands: {
      description: 'List all brands',
      parameters: {
        type: 'object' as const,
        properties: {
          name: { type: 'string', description: 'Filter by brand name (partial match)' },
          page: { type: 'number', description: 'Page number (default: 1)' },
          limit: { type: 'number', description: 'Items per page (default: 50, max: 250)' },
        },
      },
      handler: async (params: Record<string, unknown>) => {
        const queryParams: Record<string, string | number> = {};
        if (params.name) queryParams['name:like'] = params.name as string;

        const page = (params.page as number) || 1;
        const limit = (params.limit as number) || 50;

        const result = await client.getPage<Brand>('/catalog/brands', page, limit, queryParams);
        return { brands: result.data, meta: result.meta };
      },
    },

    bigcommerce_get_brand: {
      description: 'Get a single brand by ID',
      parameters: {
        type: 'object' as const,
        properties: {
          brand_id: { type: 'number', description: 'Brand ID', required: true },
        },
        required: ['brand_id'],
      },
      handler: async (params: { brand_id: number }) => {
        const result = await client.get<{ data: Brand }>(`/catalog/brands/${params.brand_id}`);
        return result.data;
      },
    },

    bigcommerce_create_brand: {
      description: 'Create a new brand',
      parameters: {
        type: 'object' as const,
        properties: {
          name: { type: 'string', description: 'Brand name', required: true },
          page_title: { type: 'string', description: 'SEO page title' },
          meta_description: { type: 'string', description: 'SEO meta description' },
          meta_keywords: { type: 'array', items: { type: 'string' }, description: 'SEO meta keywords' },
          image_url: { type: 'string', description: 'Brand logo URL' },
          search_keywords: { type: 'string', description: 'Search keywords' },
        },
        required: ['name'],
      },
      handler: async (params: Partial<Brand>) => {
        const result = await client.post<{ data: Brand }>('/catalog/brands', params);
        return result.data;
      },
    },

    bigcommerce_update_brand: {
      description: 'Update an existing brand',
      parameters: {
        type: 'object' as const,
        properties: {
          brand_id: { type: 'number', description: 'Brand ID', required: true },
          name: { type: 'string', description: 'Brand name' },
          page_title: { type: 'string', description: 'SEO page title' },
          meta_description: { type: 'string', description: 'SEO meta description' },
          image_url: { type: 'string', description: 'Brand logo URL' },
        },
        required: ['brand_id'],
      },
      handler: async (params: { brand_id: number; [key: string]: unknown }) => {
        const { brand_id, ...updateData } = params;
        const result = await client.put<{ data: Brand }>(`/catalog/brands/${brand_id}`, updateData);
        return result.data;
      },
    },

    bigcommerce_delete_brand: {
      description: 'Delete a brand',
      parameters: {
        type: 'object' as const,
        properties: {
          brand_id: { type: 'number', description: 'Brand ID', required: true },
        },
        required: ['brand_id'],
      },
      handler: async (params: { brand_id: number }) => {
        await client.delete(`/catalog/brands/${params.brand_id}`);
        return { success: true, message: `Brand ${params.brand_id} deleted` };
      },
    },

    // Bulk Operations
    bigcommerce_bulk_update_product_prices: {
      description: 'Bulk update product prices (supports price adjustments)',
      parameters: {
        type: 'object' as const,
        properties: {
          product_ids: { type: 'array', items: { type: 'number' }, description: 'Array of product IDs to update', required: true },
          price_adjustment: {
            type: 'object',
            description: 'Price adjustment settings',
            required: true,
            properties: {
              type: { type: 'string', enum: ['percentage', 'fixed'], description: 'Adjustment type', required: true },
              value: { type: 'number', description: 'Adjustment value (e.g., 10 for 10% or $10)', required: true },
            },
          },
        },
        required: ['product_ids', 'price_adjustment'],
      },
      handler: async (params: { product_ids: number[]; price_adjustment: { type: string; value: number } }) => {
        // BigCommerce doesn't have a single bulk endpoint, so we'll batch the requests
        const results = [];
        for (const productId of params.product_ids) {
          const product = await client.get<{ data: { price: number } }>(`/catalog/products/${productId}`);
          let newPrice = product.data.price;
          
          if (params.price_adjustment.type === 'percentage') {
            newPrice = product.data.price * (1 + params.price_adjustment.value / 100);
          } else {
            newPrice = product.data.price + params.price_adjustment.value;
          }

          const updated = await client.put<{ data: unknown }>(`/catalog/products/${productId}`, { price: newPrice });
          results.push(updated.data);
        }
        
        return { success: true, updated_count: results.length, products: results };
      },
    },

    bigcommerce_bulk_delete_products: {
      description: 'Bulk delete multiple products',
      parameters: {
        type: 'object' as const,
        properties: {
          product_ids: { type: 'array', items: { type: 'number' }, description: 'Array of product IDs to delete', required: true },
        },
        required: ['product_ids'],
      },
      handler: async (params: { product_ids: number[] }) => {
        const ids = params.product_ids.join(',');
        await client.delete(`/catalog/products?id:in=${ids}`);
        return { success: true, message: `Deleted ${params.product_ids.length} products` };
      },
    },
  };
}
