import type { ToolModule, ToolDefinition, ToolResult } from './types.js';
import type { GSCClient, InspectionResult } from '../lib/gsc-client.js';
import { InspectUrlSchema, BatchInspectUrlsSchema, RequestIndexingSchema } from '../schemas/indexing.js';

/**
 * INDEXING TOOLS
 * URL inspection and indexing request tools
 */

/** Helper to extract the inner inspection data */
function getInspection(result: InspectionResult) {
  return result.inspectionResult ?? {};
}

// ============================================================================
// INSPECT URL
// ============================================================================

const inspectUrl: ToolDefinition = {
  name: 'inspect_url',
  description: 'Inspect a URL\'s indexing status in Google Search. Returns coverage status, mobile usability, AMP status, structured data issues, and more.',
  category: 'indexing',
  annotations: {
    readOnlyHint: true,
    idempotentHint: true
  },
  inputSchema: InspectUrlSchema,
  _meta: {
    labels: {
      category: "indexing",
      access: "read",
      complexity: "simple"
    }
  },
  handler: async (args: any, gscClient: GSCClient): Promise<ToolResult> => {
    try {
      const raw = await gscClient.inspectUrl(args.siteUrl, args.inspectionUrl);
      const result = getInspection(raw);

      let text = `🔍 **URL Inspection: ${args.inspectionUrl}**\n\n`;

      // Index coverage
      if (result.indexStatusResult) {
        const coverage = result.indexStatusResult.coverageState || 'UNKNOWN';
        const emoji = coverage === 'Submitted and indexed' ? '✅' :
                     coverage === 'Discovered - currently not indexed' ? '⏳' :
                     coverage === 'Excluded' ? '❌' : '❓';

        text += `**Index Status:** ${emoji} ${coverage}\n`;

        if (result.indexStatusResult.verdict) {
          text += `Verdict: ${result.indexStatusResult.verdict}\n`;
        }

        if (result.indexStatusResult.lastCrawlTime) {
          text += `Last crawled: ${new Date(result.indexStatusResult.lastCrawlTime).toLocaleString()}\n`;
        }

        if (result.indexStatusResult.robotsTxtState) {
          text += `Robots.txt: ${result.indexStatusResult.robotsTxtState}\n`;
        }

        if (result.indexStatusResult.indexingState) {
          text += `Indexing state: ${result.indexStatusResult.indexingState}\n`;
        }

        if (result.indexStatusResult.pageFetchState) {
          text += `Page fetch: ${result.indexStatusResult.pageFetchState}\n`;
        }

        text += `\n`;
      }

      // Mobile usability
      if (result.mobileUsabilityResult) {
        const verdict = result.mobileUsabilityResult.verdict || 'UNKNOWN';
        const emoji = verdict === 'PASS' ? '✅' : verdict === 'FAIL' ? '❌' : '❓';
        text += `**Mobile Usability:** ${emoji} ${verdict}\n`;

        if (result.mobileUsabilityResult.issues && result.mobileUsabilityResult.issues.length > 0) {
          text += `Issues:\n`;
          result.mobileUsabilityResult.issues.forEach((issue: any) => {
            text += `  • ${issue.issueType}: ${issue.message}\n`;
          });
        }
        text += `\n`;
      }

      // Rich results
      if (result.richResultsResult) {
        const verdict = result.richResultsResult.verdict || 'UNKNOWN';
        const emoji = verdict === 'PASS' ? '✅' : verdict === 'FAIL' ? '❌' : '❓';
        text += `**Rich Results:** ${emoji} ${verdict}\n`;

        if (result.richResultsResult.detectedItems && result.richResultsResult.detectedItems.length > 0) {
          text += `Detected items:\n`;
          result.richResultsResult.detectedItems.forEach((item: any) => {
            text += `  • ${item.richResultType || 'Unknown type'}\n`;
          });
        }
        text += `\n`;
      }

      return {
        content: [{ type: 'text', text }],
        structuredContent: raw
      };
    } catch (error) {
      return {
        content: [{
          type: 'text',
          text: `Error inspecting URL: ${error instanceof Error ? error.message : String(error)}`
        }],
        isError: true
      };
    }
  }
};

// ============================================================================
// BATCH INSPECT URLS
// ============================================================================

const batchInspectUrls: ToolDefinition = {
  name: 'batch_inspect_urls',
  description: 'Inspect multiple URLs in parallel (up to 50 at once). Returns a summary of indexed vs not-indexed URLs plus individual inspection results.',
  category: 'indexing',
  annotations: {
    readOnlyHint: true,
    idempotentHint: true
  },
  inputSchema: BatchInspectUrlsSchema,
  _meta: {
    labels: {
      category: "indexing",
      access: "read",
      complexity: "batch"
    }
  },
  handler: async (args: any, gscClient: GSCClient): Promise<ToolResult> => {
    try {
      const results: Array<{
        url: string;
        inspection: ReturnType<typeof getInspection> | null;
        error: string | null;
      }> = [];
      const concurrency = 5;

      for (let i = 0; i < args.urls.length; i += concurrency) {
        const batch = args.urls.slice(i, i + concurrency);
        const batchResults = await Promise.allSettled(
          batch.map((url: string) => gscClient.inspectUrl(args.siteUrl, url))
        );

        results.push(...batchResults.map((result, idx) => ({
          url: batch[idx],
          inspection: result.status === 'fulfilled' ? getInspection(result.value) : null,
          error: result.status === 'rejected' ? String(result.reason) : null
        })));
      }

      // Calculate summary
      const total = results.length;
      let indexed = 0;
      let notIndexed = 0;
      let errors = 0;

      for (const r of results) {
        if (r.error) {
          errors++;
        } else if (r.inspection?.indexStatusResult?.coverageState === 'Submitted and indexed') {
          indexed++;
        } else {
          notIndexed++;
        }
      }

      let text = `📊 **Batch URL Inspection: ${total} URLs**\n\n`;
      text += `✅ Indexed: ${indexed}\n`;
      text += `❌ Not indexed: ${notIndexed}\n`;
      text += `⚠️ Errors: ${errors}\n\n`;
      text += `---\n\n`;

      results.forEach((r, idx) => {
        text += `**${idx + 1}. ${r.url}**\n`;

        if (r.error) {
          text += `   ⚠️ Error: ${r.error}\n\n`;
        } else if (r.inspection?.indexStatusResult) {
          const coverage = r.inspection.indexStatusResult.coverageState || 'UNKNOWN';
          const emoji = coverage === 'Submitted and indexed' ? '✅' :
                       coverage === 'Discovered - currently not indexed' ? '⏳' :
                       coverage === 'Excluded' ? '❌' : '❓';

          text += `   ${emoji} ${coverage}\n`;

          if (r.inspection.indexStatusResult.verdict) {
            text += `   Verdict: ${r.inspection.indexStatusResult.verdict}\n`;
          }

          if (r.inspection.indexStatusResult.lastCrawlTime) {
            text += `   Last crawled: ${new Date(r.inspection.indexStatusResult.lastCrawlTime).toLocaleDateString()}\n`;
          }

          if (r.inspection.mobileUsabilityResult?.verdict === 'FAIL') {
            text += `   ⚠️ Mobile usability issues detected\n`;
          }

          if (r.inspection.richResultsResult?.verdict === 'FAIL') {
            text += `   ⚠️ Rich results issues detected\n`;
          }

          text += `\n`;
        }
      });

      return {
        content: [{ type: 'text', text }],
        structuredContent: {
          summary: { total, indexed, notIndexed, errors },
          results: results.map(r => ({
            url: r.url,
            coverageState: r.inspection?.indexStatusResult?.coverageState || null,
            verdict: r.inspection?.indexStatusResult?.verdict || null,
            lastCrawlTime: r.inspection?.indexStatusResult?.lastCrawlTime || null,
            mobileUsability: r.inspection?.mobileUsabilityResult?.verdict || null,
            richResults: r.inspection?.richResultsResult?.verdict || null,
            error: r.error
          }))
        }
      };
    } catch (error) {
      return {
        content: [{
          type: 'text',
          text: `Error in batch inspection: ${error instanceof Error ? error.message : String(error)}`
        }],
        isError: true
      };
    }
  }
};

// ============================================================================
// REQUEST INDEXING
// ============================================================================

const requestIndexing: ToolDefinition = {
  name: 'request_indexing',
  description: 'Request Google to index or re-index a URL. Use this after publishing new content or making significant updates. Note: Limited to 200 requests/day per project.',
  category: 'indexing',
  annotations: {
    readOnlyHint: false,
    idempotentHint: true,
    openWorldHint: true
  },
  inputSchema: RequestIndexingSchema,
  _meta: {
    labels: {
      category: "indexing",
      access: "write",
      complexity: "simple"
    }
  },
  handler: async (args: any, gscClient: GSCClient): Promise<ToolResult> => {
    try {
      await gscClient.requestIndexing(args.url);

      let text = `✅ **Indexing Request Submitted**\n\n`;
      text += `URL: ${args.url}\n\n`;
      text += `Google has received your indexing request. The URL will be crawled and processed according to normal crawl priorities.\n\n`;
      text += `⚠️ **Important notes:**\n`;
      text += `• Daily quota: 200 requests per project\n`;
      text += `• Processing time: Hours to days depending on site authority and crawl budget\n`;
      text += `• This does NOT guarantee immediate indexing\n`;
      text += `• Use sparingly for important URLs only\n`;

      return {
        content: [{ type: 'text', text }],
        structuredContent: {
          url: args.url,
          status: 'submitted',
          timestamp: new Date().toISOString()
        }
      };
    } catch (error) {
      const errorMsg = error instanceof Error ? error.message : String(error);

      if (errorMsg.includes('quota') || errorMsg.includes('limit')) {
        return {
          content: [{
            type: 'text',
            text: `❌ **Quota Exceeded**\n\nYou've reached the daily limit of 200 indexing requests. Quota resets at midnight Pacific Time.\n\nError: ${errorMsg}`
          }],
          isError: true
        };
      }

      return {
        content: [{
          type: 'text',
          text: `Error requesting indexing: ${errorMsg}`
        }],
        isError: true
      };
    }
  }
};

// ============================================================================
// EXPORTS
// ============================================================================

export const indexingTools: ToolModule = {
  tools: [
    inspectUrl,
    batchInspectUrls,
    requestIndexing
  ]
};
