/**
 * Support Issue Reporting Utility
 * Formats error information for reporting to support/GitHub issues
 */

import type { ApiError } from '@/schemas/apiSchemas';
import { parseApiError } from './apiErrorHandler';
import { getErrorCategory } from './apiErrorHandler';

export interface IssueReport {
  title: string;
  body: string;
  metadata: {
    requestId?: string;
    errorCode?: string | number;
    statusCode?: number;
    category: string;
    timestamp: string;
    userAgent: string;
    url: string;
  };
}

/**
 * Formats an error into a structured issue report
 * @param error - The error to report (ApiError, Error, or unknown)
 * @param context - Additional context about where/why the error occurred
 * @returns Formatted issue report
 */
export function formatIssueReport(
  error: Error | ApiError | unknown,
  context?: {
    component?: string;
    action?: string;
    userId?: string;
    additionalInfo?: Record<string, any>;
  },
): IssueReport {
  const apiError = parseApiError(error);
  const category = getErrorCategory(apiError);

  // Get browser/environment info
  const userAgent =
    typeof navigator !== 'undefined' ? navigator.userAgent : 'Unknown';
  const url = typeof window !== 'undefined' ? window.location.href : 'Unknown';
  const timestamp = new Date().toISOString();

  // Build title
  const title = `[${category.toUpperCase()}] ${apiError.message || 'Unknown error'}`;

  // Build body with structured information
  const sections: string[] = [];

  // Error details section
  sections.push('## 🐞 Error Details');
  sections.push('');
  sections.push(`**Message:** ${apiError.message || 'No message provided'}`);

  if (apiError.code !== undefined) {
    sections.push(`**Error Code:** ${apiError.code}`);
  }

  if (apiError.status !== undefined) {
    sections.push(`**HTTP Status:** ${apiError.status}`);
  }

  if (apiError.request_id) {
    sections.push(`**Request ID:** \`${apiError.request_id}\``);
  }

  sections.push(`**Category:** ${category}`);
  sections.push(`**Timestamp:** ${timestamp}`);
  sections.push('');

  // Context section
  if (context) {
    sections.push('## 📍 Context');
    sections.push('');

    if (context.component) {
      sections.push(`**Component:** ${context.component}`);
    }

    if (context.action) {
      sections.push(`**Action:** ${context.action}`);
    }

    if (context.userId) {
      sections.push(`**User ID:** ${context.userId}`);
    }

    if (
      context.additionalInfo &&
      Object.keys(context.additionalInfo).length > 0
    ) {
      sections.push('**Additional Info:**');
      sections.push('```json');
      sections.push(JSON.stringify(context.additionalInfo, null, 2));
      sections.push('```');
    }

    sections.push('');
  }

  // Error details section
  if (apiError.details) {
    sections.push('## 🔍 Error Details');
    sections.push('');
    sections.push('```json');
    sections.push(JSON.stringify(apiError.details, null, 2));
    sections.push('```');
    sections.push('');
  }

  // Validation errors section
  if (apiError.errors && Object.keys(apiError.errors).length > 0) {
    sections.push('## ⚠️ Validation Errors');
    sections.push('');
    Object.entries(apiError.errors).forEach(([field, messages]) => {
      sections.push(
        `- **${field}:** ${Array.isArray(messages) ? messages.join(', ') : messages}`,
      );
    });
    sections.push('');
  }

  // Environment section
  sections.push('## 💻 Environment');
  sections.push('');
  sections.push(`**URL:** ${url}`);
  sections.push(`**User Agent:** ${userAgent}`);
  sections.push(`**Browser:** ${getBrowserName(userAgent)}`);
  sections.push(`**Platform:** ${getPlatformName(userAgent)}`);

  if (typeof window !== 'undefined') {
    sections.push(`**Screen:** ${window.screen.width}x${window.screen.height}`);
    sections.push(`**Viewport:** ${window.innerWidth}x${window.innerHeight}`);
  }

  sections.push('');

  // Steps to reproduce (placeholder)
  sections.push('## 🔁 Steps to Reproduce');
  sections.push('');
  sections.push('1. [Describe step 1]');
  sections.push('2. [Describe step 2]');
  sections.push('3. [Describe step 3]');
  sections.push('');

  // Expected behavior
  sections.push('## ✅ Expected Behavior');
  sections.push('');
  sections.push('[Describe what should have happened]');
  sections.push('');

  const body = sections.join('\n');

  return {
    title,
    body,
    metadata: {
      requestId: apiError.request_id,
      errorCode: apiError.code,
      statusCode: apiError.status,
      category,
      timestamp,
      userAgent,
      url,
    },
  };
}

/**
 * Copies issue report to clipboard
 * @param report - The issue report to copy
 * @returns Promise that resolves when copy is complete
 */
export async function copyIssueReportToClipboard(
  report: IssueReport,
): Promise<void> {
  const text = `${report.title}\n\n${report.body}`;

  if (
    typeof navigator !== 'undefined' &&
    navigator.clipboard &&
    navigator.clipboard.writeText
  ) {
    try {
      await navigator.clipboard.writeText(text);
      return;
    } catch (err) {
      // Fallback to legacy method
    }
  }

  // Fallback: create temporary textarea
  const textarea = document.createElement('textarea');
  textarea.value = text;
  textarea.style.position = 'fixed';
  textarea.style.opacity = '0';
  document.body.appendChild(textarea);
  textarea.select();

  try {
    document.execCommand('copy');
  } finally {
    document.body.removeChild(textarea);
  }
}

/**
 * Opens GitHub issue creation page with pre-filled issue report
 * @param report - The issue report to use
 * @param repository - GitHub repository (default: uses current repo if available)
 */
export function openGitHubIssue(
  report: IssueReport,
  repository?: string,
): void {
  // Try to detect repository from package.json or env
  const repo = repository || getRepositoryUrl();

  if (!repo) {
    // Fallback: just copy to clipboard
    copyIssueReportToClipboard(report);
    return;
  }

  // GitHub issue URL format: https://github.com/owner/repo/issues/new?title=...&body=...
  const params = new URLSearchParams({
    title: report.title,
    body: report.body,
  });

  const url = `${repo}/issues/new?${params.toString()}`;
  window.open(url, '_blank');
}

/**
 * Gets repository URL from package.json or environment
 */
function getRepositoryUrl(): string | null {
  // Try to get from environment variable
  if (import.meta.env.VITE_GITHUB_REPO) {
    return `https://github.com/${import.meta.env.VITE_GITHUB_REPO}`;
  }

  // Try to parse from package.json repository field (would need to be passed or read)
  // For now, return null and fallback to clipboard
  return null;
}

/**
 * Extracts browser name from user agent
 */
function getBrowserName(userAgent: string): string {
  if (userAgent.includes('Chrome') && !userAgent.includes('Edg'))
    return 'Chrome';
  if (userAgent.includes('Firefox')) return 'Firefox';
  if (userAgent.includes('Safari') && !userAgent.includes('Chrome'))
    return 'Safari';
  if (userAgent.includes('Edg')) return 'Edge';
  if (userAgent.includes('Opera') || userAgent.includes('OPR')) return 'Opera';
  return 'Unknown';
}

/**
 * Extracts platform name from user agent
 */
function getPlatformName(userAgent: string): string {
  if (userAgent.includes('Windows')) return 'Windows';
  if (userAgent.includes('Mac')) return 'macOS';
  if (userAgent.includes('Linux')) return 'Linux';
  if (userAgent.includes('Android')) return 'Android';
  if (
    userAgent.includes('iOS') ||
    userAgent.includes('iPhone') ||
    userAgent.includes('iPad')
  )
    return 'iOS';
  return 'Unknown';
}
