/**
 * Templates for generating React service context
 */

export interface DomainInfo {
  name: string;
  capitalizedName: string;
}

/**
 * Generate empty service context template
 */
export const getEmptyServiceContextTemplate = (): string => {
  return `import React, { createContext, useContext } from 'react';

// Configuration de base
const API_BASE_URL = process.env.REACT_APP_API_BASE_URL || '/api';

// Type pour les services
interface Services {
  // Services will be added here when domains are created
}

// Services par défaut
const defaultServices: Services = {
  // Default services will be initialized here
};

// Création du contexte
const ServiceContext = createContext<Services>(defaultServices);

// Provider pour injection de dépendances
export const ServiceProvider: React.FC<{
  services?: Partial<Services>;
  children: React.ReactNode;
}> = ({ services, children }) => {
  const value = { ...defaultServices, ...services };

  return (
    <ServiceContext.Provider value={value}>
      {children}
    </ServiceContext.Provider>
  );
};

// Hook pour utiliser les services
export const useServices = () => useContext(ServiceContext);
`;
};

/**
 * Generate service context template with domains
 */
export const getServiceContextTemplate = (domains: DomainInfo[]): string => {
  const imports = domains
    .map(domain => 
      `import { ${domain.capitalizedName}Service } from '../domains/${domain.name}/services/${domain.capitalizedName}Service';\n` +
      `import { ${domain.capitalizedName}Adapter } from '../domains/${domain.name}/adapters/${domain.capitalizedName}Adapter';`
    )
    .join('\n');

  const serviceTypes = domains
    .map(domain => `  ${domain.name}Service: ${domain.capitalizedName}Service;`)
    .join('\n');

  const adapterCreations = domains
    .map(domain => `const ${domain.name}Repository = new ${domain.capitalizedName}Adapter();`)
    .join('\n');

  const serviceCreations = domains
    .map(domain => `const ${domain.name}Service = new ${domain.capitalizedName}Service(${domain.name}Repository);`)
    .join('\n');

  const defaultServiceProps = domains
    .map(domain => `  ${domain.name}Service,`)
    .join('\n');

  return `import React, { createContext, useContext } from 'react';

// Import des services et adaptateurs
${imports}

// Création des adaptateurs
${adapterCreations}

// Création des services avec leurs dépendances
${serviceCreations}

// Type pour les services
interface Services {
${serviceTypes}
}

// Services par défaut
const defaultServices: Services = {
${defaultServiceProps}
};

// Création du contexte
const ServiceContext = createContext<Services>(defaultServices);

// Provider pour injection de dépendances
export const ServiceProvider: React.FC<{
  services?: Partial<Services>;
  children: React.ReactNode;
}> = ({ services, children }) => {
  const value = { ...defaultServices, ...services };

  return (
    <ServiceContext.Provider value={value}>
      {children}
    </ServiceContext.Provider>
  );
};

// Hook pour utiliser les services
export const useServices = () => useContext(ServiceContext);
`;
};

/**
 * Generate test template for service context
 */
export const getServiceContextTestTemplate = (domains: DomainInfo[]): string => {
  const mockServices = domains
    .map(domain => `  ${domain.name}Service: {} as ${domain.capitalizedName}Service,`)
    .join('\n');

  const serviceImports = domains
    .map(domain => `import { ${domain.capitalizedName}Service } from '../domains/${domain.name}/services/${domain.capitalizedName}Service';`)
    .join('\n');

  return `import React from 'react';
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { ServiceProvider, useServices } from './ServiceContext';
${serviceImports}

// Mock services
const mockServices = {
${mockServices}
};

// Test component to access services
const TestComponent: React.FC = () => {
  const services = useServices();
  return (
    <div>
      <div data-testid="services-count">{Object.keys(services).length}</div>
      {Object.keys(services).map(key => (
        <div key={key} data-testid={\`service-\${key}\`}>
          {key}
        </div>
      ))}
    </div>
  );
};

describe('ServiceContext', () => {
  it('should provide default services', () => {
    render(
      <ServiceProvider>
        <TestComponent />
      </ServiceProvider>
    );

    expect(screen.getByTestId('services-count')).toHaveTextContent('${domains.length}');
${domains.map(domain => `    expect(screen.getByTestId('service-${domain.name}Service')).toBeInTheDocument();`).join('\n')}
  });

  it('should allow service override', () => {
    render(
      <ServiceProvider services={mockServices}>
        <TestComponent />
      </ServiceProvider>
    );

    expect(screen.getByTestId('services-count')).toHaveTextContent('${domains.length}');
  });

  it('should provide services through useServices hook', () => {
    let capturedServices: any;
    
    const TestHook: React.FC = () => {
      capturedServices = useServices();
      return null;
    };

    render(
      <ServiceProvider>
        <TestHook />
      </ServiceProvider>
    );

    expect(capturedServices).toBeDefined();
    expect(Object.keys(capturedServices)).toHaveLength(${domains.length});
${domains.map(domain => `    expect(capturedServices.${domain.name}Service).toBeDefined();`).join('\n')}
  });
});
`;
}; 