import { 
  AdminFeature, 
  AdminNotification, 
  FeatureSimilarity, 
  FeatureReviewData, 
  AdminStats,
  FeatureSynonym,
  AdminApiResponse,
  AdminTemplate
} from '@/types/admin.types';
import { getAccessToken } from '@/components/apis/authApiClients';
import { BACKEND_URL } from '@/config/backend';

const API_BASE_URL = BACKEND_URL;
const AUTH_API_BASE_URL = BACKEND_URL;

// Helper function to make API calls
async function apiCall<T>(
  endpoint: string, 
  options: RequestInit = {},
  useAuthAPI = false
): Promise<AdminApiResponse<T>> {
  const baseUrl = useAuthAPI ? AUTH_API_BASE_URL : API_BASE_URL;
  const url = `${baseUrl}${endpoint}`;
  
  const token = getAccessToken();
  const defaultHeaders: Record<string, string> = {
    'Content-Type': 'application/json',
  };
  if (token) {
    defaultHeaders['Authorization'] = `Bearer ${token}`;
  }

  const response = await fetch(url, {
    ...options,
    headers: {
      ...defaultHeaders,
      ...options.headers,
    },
  });

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({}));
    const err = new AdminApiError(
      errorData.message || `HTTP error! status: ${response.status}`,
      response.status,
      errorData.code
    );
    // Attach full server payload for consumers that need richer context
    (err as AdminApiError & { data: Record<string, unknown> }).data = errorData;
    throw err;
  }

  return response.json();
}

// Admin Feature Management API
export const adminApi = {
  // Get pending features
  getPendingFeatures: async (limit = 50, offset = 0): Promise<AdminFeature[]> => {
    const response = await apiCall<AdminFeature[]>(`/api/auth/admin/custom-features?status=pending&limit=${limit}&offset=${offset}`, {}, true);
    return response.data;
  },

  // Get features by status
  getFeaturesByStatus: async (status: string, limit = 50, offset = 0): Promise<AdminFeature[]> => {
    const response = await apiCall<AdminFeature[]>(`/api/auth/admin/custom-features?status=${status}&limit=${limit}&offset=${offset}`, {}, true);
    return response.data;
  },

  // Get feature statistics
  getFeatureStats: async (): Promise<AdminStats> => {
    const response = await apiCall<AdminStats>('/api/auth/admin/custom-features', {}, true);
    return response.data;
  },

  // Review a feature
  reviewFeature: async (featureId: string, reviewData: FeatureReviewData): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/auth/admin/custom-features/${featureId}/review`, {
      method: 'PUT',
      body: JSON.stringify(reviewData),
    }, true);
    return response.data;
  },

  // Find similar features
  findSimilarFeatures: async (query: string, threshold = 0.7, limit = 5): Promise<FeatureSimilarity[]> => {
    const response = await apiCall<FeatureSimilarity[]>(
      `/api/features/similar?q=${encodeURIComponent(query)}&threshold=${threshold}&limit=${limit}`
    );
    return response.data;
  },

  // Add feature synonym
  addFeatureSynonym: async (featureId: string, synonym: string, createdBy?: string): Promise<FeatureSynonym> => {
    const response = await apiCall<FeatureSynonym>(`/api/features/${featureId}/synonyms`, {
      method: 'POST',
      body: JSON.stringify({ synonym, created_by: createdBy }),
    });
    return response.data;
  },

  // Get feature synonyms
  getFeatureSynonyms: async (featureId: string): Promise<FeatureSynonym[]> => {
    const response = await apiCall<FeatureSynonym[]>(`/api/features/${featureId}/synonyms`);
    return response.data;
  },

  // Get admin notifications
  getNotifications: async (unreadOnly = false, limit = 50, offset = 0): Promise<AdminNotification[]> => {
    const response = await apiCall<AdminNotification[]>(
      `/api/admin/notifications?unread_only=${unreadOnly}&limit=${limit}&offset=${offset}`
    );
    return response.data;
  },

  // Mark notification as read
  markNotificationAsRead: async (notificationId: string): Promise<AdminNotification> => {
    const response = await apiCall<AdminNotification>(`/api/admin/notifications/${notificationId}/read`, {
      method: 'POST',
    });
    return response.data;
  },

  // Mark all notifications as read
  markAllNotificationsAsRead: async (): Promise<{ count: number }> => {
    const response = await apiCall<{ count: number }>('/api/admin/notifications/read-all', {
      method: 'POST',
    });
    return response.data;
  },

  // Get custom features (from user-auth admin API)
  getCustomFeatures: async (status?: string, limit = 50, offset = 0): Promise<AdminFeature[]> => {
    const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString() });
    if (status) params.append('status', status);
    const response = await apiCall<AdminFeature[]>(`/api/auth/admin/custom-features?${params}`, {}, true);
    return response.data;
  },

  // Get custom templates (from user-auth admin API)
  getCustomTemplates: async (status?: string, limit = 50, offset = 0): Promise<AdminTemplate[]> => {
    const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString() });
    if (status) params.append('status', status);
    const response = await apiCall<AdminTemplate[]>(`/api/auth/admin/custom-templates?${params}`, {}, true);
    return response.data;
  },

  // Review custom feature (from user-auth admin API)
  reviewCustomFeature: async (featureId: string, reviewData: { status: string; admin_notes?: string }): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/auth/admin/custom-features/${featureId}/review`, {
      method: 'PUT',
      body: JSON.stringify(reviewData),
    }, true);
    return response.data;
  },

  // Review custom template (from user-auth admin API)
  reviewTemplate: async (templateId: string, reviewData: { status: string; admin_notes?: string }): Promise<Record<string, unknown>> => {
    const response = await apiCall<Record<string, unknown>>(`/api/auth/admin/custom-templates/${templateId}/review`, {
      method: 'PUT',
      body: JSON.stringify(reviewData),
    }, true);
    return response.data;
  },

  // Reject custom feature
  rejectCustomFeature: async (featureId: string, adminNotes?: string): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/auth/admin/custom-features/${featureId}/review`, {
      method: 'PUT',
      body: JSON.stringify({ 
        status: 'rejected', 
        admin_notes: adminNotes || 'Rejected by admin'
      }),
    }, true);
    return response.data;
  },

  // Reject custom template
  rejectTemplate: async (templateId: string, adminNotes?: string): Promise<Record<string, unknown>> => {
    const response = await apiCall<Record<string, unknown>>(`/api/auth/admin/custom-templates/${templateId}/review`, {
      method: 'PUT',
      body: JSON.stringify({ 
        status: 'rejected', 
        admin_notes: adminNotes || 'Rejected by admin' 
      }),
    }, true);
    return response.data;
  },

  // Update custom feature
  updateCustomFeature: async (featureId: string, updateData: {
    name?: string;
    description?: string;
    complexity?: 'low' | 'medium' | 'high';
    business_rules?: Record<string, unknown>;
    technical_requirements?: Record<string, unknown>;
  }): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/features/${featureId}`, {
      method: 'PUT',
      body: JSON.stringify(updateData),
    });
    return response.data;
  },

  // Create new template from edit (creates new record instead of updating)
  createTemplateFromEdit: async (originalTemplateId: string, updateData: {
    title?: string;
    description?: string;
    category?: string;
    type?: string;
    icon?: string;
    gradient?: string;
    border?: string;
    text?: string;
    subtext?: string;
  }): Promise<Record<string, unknown>> => {
    const response = await apiCall<Record<string, unknown>>(`/api/templates`, {
      method: 'POST',
      body: JSON.stringify({
        ...updateData,
        is_custom: true,
        isCustom: true,
        status: 'pending',
        created_from_edit: originalTemplateId
      }),
    }, false);
    return response.data;
  },

  // Create approved template in main templates table
  createApprovedTemplate: async (customTemplateId: string, templateData: {
    title: string;
    description?: string;
    category: string;
    type: string;
    icon?: string;
    gradient?: string;
    border?: string;
    text?: string;
    subtext?: string;
  }): Promise<Record<string, unknown>> => {
    // Use dedicated endpoint that also approves the custom template server-side
    const response = await apiCall<Record<string, unknown>>(`/api/templates/approve-custom`, {
      method: 'POST',
      body: JSON.stringify({
        custom_template_id: customTemplateId,
        template: {
          ...templateData,
          is_custom: false,
          isCustom: false
        }
      }),
    }, false);
    return response.data;
  },

  // Create feature directly in template_features table
  createApprovedFeature: async (featureData: {
    template_id: string;
    name: string;
    description?: string;
    complexity: 'low' | 'medium' | 'high';
    business_rules?: Record<string, unknown>;
    technical_requirements?: Record<string, unknown>;
    feature_type?: string;
  }): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/features`, {
      method: 'POST',
      body: JSON.stringify(featureData),
    }, false);
    return response.data;
  },

  // Get single custom feature by ID
  getCustomFeature: async (featureId: string): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/features/${featureId}`);
    return response.data;
  },

  // Get single custom template by ID
  getCustomTemplate: async (templateId: string): Promise<Record<string, unknown>> => {
    const response = await apiCall<Record<string, unknown>>(`/api/templates/${templateId}`);
    return response.data;
  },

  // Get custom feature stats
  getCustomFeatureStats: async (): Promise<AdminStats> => {
    const response = await apiCall<AdminStats>('/api/admin/features/stats');
    return response.data;
  },

  // Get template stats
  getTemplateStats: async (): Promise<AdminStats> => {
    const response = await apiCall<AdminStats>('/api/admin/templates/stats');
    return response.data;
  },

  // Create new custom template
  createCustomTemplate: async (templateData: {
    title: string;
    description: string;
    category: string;
    type: string;
    complexity: string;
    icon?: string;
    gradient?: string;
    border?: string;
    text?: string;
    subtext?: string;
  }): Promise<Record<string, unknown>> => {
    const response = await apiCall<Record<string, unknown>>('/api/templates', {
      method: 'POST',
      body: JSON.stringify({
        ...templateData
      }),
    }, false);
    return response.data;
  },

  // Template Features Management
  // Get features for a specific template
  getTemplateFeatures: async (templateId: string): Promise<AdminFeature[]> => {
    const response = await apiCall<AdminFeature[]>(`/api/templates/${templateId}/features`);
    return response.data;
  },

  // Add feature to template
  addFeatureToTemplate: async (templateId: string, featureData: {
    name: string;
    description?: string;
    complexity: 'low' | 'medium' | 'high';
    business_rules?: Record<string, unknown>;
    technical_requirements?: Record<string, unknown>;
    feature_type?: string;
  }): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/templates/${templateId}/features`, {
      method: 'POST',
      body: JSON.stringify(featureData),
    });
    return response.data;
  },

  // Update feature in template
  updateTemplateFeature: async (templateId: string, featureId: string, updateData: {
    name?: string;
    description?: string;
    complexity?: 'low' | 'medium' | 'high';
    business_rules?: Record<string, unknown>;
    technical_requirements?: Record<string, unknown>;
    feature_type?: string;
  }): Promise<AdminFeature> => {
    const response = await apiCall<AdminFeature>(`/api/templates/${templateId}/features/${featureId}`, {
      method: 'PUT',
      body: JSON.stringify(updateData),
    });
    return response.data;
  },

  // Remove feature from template
  removeFeatureFromTemplate: async (templateId: string, featureId: string): Promise<void> => {
    await apiCall<void>(`/api/templates/${templateId}/features/${featureId}`, {
      method: 'DELETE',
    });
  },

  // Bulk add features to template
  bulkAddFeaturesToTemplate: async (templateId: string, features: Array<{
    name: string;
    description?: string;
    complexity: 'low' | 'medium' | 'high';
    business_rules?: Record<string, unknown>;
    technical_requirements?: Record<string, unknown>;
    feature_type?: string;
  }>): Promise<AdminFeature[]> => {
    const response = await apiCall<AdminFeature[]>(`/api/templates/${templateId}/features/bulk`, {
      method: 'POST',
      body: JSON.stringify({ features }),
    });
    return response.data;
  },

  // Admin Templates Management (from main templates table)
  // Get all admin templates for management (returns data + pagination)
  getAdminTemplates: async (
    limit = 50,
    offset = 0,
    category?: string,
    search?: string
  ): Promise<{ templates: AdminTemplate[]; pagination?: { total: number; limit: number; offset: number; hasMore: boolean } }> => {
    const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString() });
    if (category && category !== 'all') params.append('category', category);
    if (search) params.append('search', search);
    const response = await apiCall<AdminTemplate[]>(`/api/admin/templates?${params}`);
    const pagination = (response as unknown as { pagination?: { total: number; limit: number; offset: number; hasMore: boolean } }).pagination;
    return { templates: response.data, pagination };
  },

  // Update an admin template (main templates table)
  updateAdminTemplate: async (
    templateId: string,
    updateData: {
      title?: string;
      description?: string;
      category?: string;
      type?: string;
      icon?: string;
      gradient?: string;
      border?: string;
      text?: string;
      subtext?: string;
    }
  ): Promise<AdminTemplate> => {
    const response = await apiCall<AdminTemplate>(`/api/admin/templates/${templateId}`, {
      method: 'PUT',
      body: JSON.stringify(updateData),
    });
    return response.data;
  },

  // Delete an admin template (main templates table)
  deleteAdminTemplate: async (templateId: string): Promise<{ success: boolean }> => {
    const response = await apiCall<{ success: boolean }>(`/api/admin/templates/${templateId}`, {
      method: 'DELETE',
    });
    return response.data;
  },

  // Get admin template statistics
  getAdminTemplateStats: async (): Promise<AdminStats> => {
    const response = await apiCall<AdminStats>('/api/admin/templates/stats');
    return response.data;
  },
};

// Feature submission API (for regular users)
export const featureApi = {
  // Submit a new custom feature
  submitCustomFeature: async (featureData: {
    template_id: string;
    name: string;
    description?: string;
    complexity: 'low' | 'medium' | 'high';
    business_rules?: Record<string, unknown>;
    technical_requirements?: Record<string, unknown>;
    created_by_user_session?: string;
  }): Promise<{ data: AdminFeature; similarityInfo?: Record<string, unknown> }> => {
    const normalizeJsonField = (value: unknown): unknown => {
      if (value === undefined || value === null || value === '') return undefined;
      if (typeof value === 'string') {
        try {
          const t = value.trim();
          if ((t.startsWith('{') && t.endsWith('}')) || (t.startsWith('[') && t.endsWith(']'))) {
            return JSON.parse(t);
          }
          return value;
        } catch {
          return undefined;
        }
      }
      return value;
    };

    const cleaned = {
      ...featureData,
      business_rules: normalizeJsonField(featureData.business_rules) as Record<string, unknown>,
      technical_requirements: normalizeJsonField(featureData.technical_requirements) as Record<string, unknown>,
    };

    const response = await apiCall<AdminFeature>('/api/features/custom', {
      method: 'POST',
      body: JSON.stringify(cleaned),
    });
    
    return {
      data: response.data,
      similarityInfo: (response as AdminApiResponse<AdminFeature> & { similarityInfo?: Record<string, unknown> }).similarityInfo,
    };
  },

  // Find similar features (for users)
  findSimilarFeatures: async (query: string, threshold = 0.7, limit = 5): Promise<FeatureSimilarity[]> => {
    const response = await apiCall<FeatureSimilarity[]>(
      `/api/features/similar?q=${encodeURIComponent(query)}&threshold=${threshold}&limit=${limit}`
    );
    return response.data;
  },
};

// Error handling utilities
export class AdminApiError extends Error {
  constructor(
    message: string,
    public status?: number,
    public code?: string
  ) {
    super(message);
    this.name = 'AdminApiError';
  }
}

// Utility functions
export const formatDate = (dateString: string): string => {
  return new Date(dateString).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
};

export const getStatusColor = (status: string): string => {
  switch (status) {
    case 'pending':
      return 'bg-yellow-100 text-yellow-800';
    case 'approved':
      return 'bg-green-100 text-green-800';
    case 'rejected':
      return 'bg-red-100 text-red-800';
    case 'duplicate':
      return 'bg-orange-100 text-orange-800';
    default:
      return 'bg-gray-100 text-gray-800';
  }
};

export const getComplexityColor = (complexity: string): string => {
  switch (complexity) {
    case 'low':
      return 'bg-green-100 text-green-800';
    case 'medium':
      return 'bg-yellow-100 text-yellow-800';
    case 'high':
      return 'bg-red-100 text-red-800';
    default:
      return 'bg-gray-100 text-gray-800';
  }
};
