import { useEffect, useRef, useState } from 'react';
import SwaggerUI from 'swagger-ui-react';
import 'swagger-ui-react/swagger-ui.css';
import { env } from '@/config/env';
import { logger } from '@/utils/logger';
import { AlertCircle, RefreshCw } from 'lucide-react';
import { Button } from '@/components/ui/button';

interface SwaggerUIProps {
  specUrl?: string;
  spec?: object;
  useIframe?: boolean; // Option pour utiliser un iframe au lieu du composant React
}

/**
 * Composant Swagger UI pour afficher la documentation API
 * Charge le fichier OpenAPI depuis le backend ou utilise un spec fourni
 * Peut utiliser un iframe pour charger Swagger UI HTML directement
 */
export function SwaggerUIDoc({ specUrl, spec, useIframe = false }: SwaggerUIProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const iframeRef = useRef<HTMLIFrameElement>(null);
  const [error, setError] = useState<string | null>(null);

  // Construire l'URL du fichier OpenAPI/Swagger ou Swagger UI HTML
  const getOpenApiUrl = () => {
    if (specUrl) return specUrl;
    
    // Si API_URL est relatif, construire l'URL complète
    const apiBase = env.API_URL.startsWith('http')
      ? env.API_URL
      : `${window.location.origin}${env.API_URL}`;
    
    const baseUrl = apiBase.replace(/\/api\/v1$/, '');
    
    // Si useIframe est true, retourner l'URL de Swagger UI HTML
    if (useIframe) {
      return `${baseUrl}/swagger/index.html`;
    }
    
    // Sinon, essayer de charger le JSON Swagger
    // gin-swagger peut servir le JSON à différents endroits
    // Essayer /swagger/doc.json (endpoint standard gin-swagger)
    return `${baseUrl}/swagger/doc.json`;
  };

  const getSwaggerUIUrl = () => {
    const apiBase = env.API_URL.startsWith('http')
      ? env.API_URL
      : `${window.location.origin}${env.API_URL}`;
    const baseUrl = apiBase.replace(/\/api\/v1$/, '');
    return `${baseUrl}/swagger/index.html`;
  };


  useEffect(() => {
    if (containerRef.current) {
      logger.debug('Swagger UI initialized', {
        specUrl: specUrl || getOpenApiUrl(),
        hasSpec: !!spec,
        useIframe,
      });
    }
  }, [specUrl, spec, useIframe]);

  const swaggerConfig = {
    url: spec ? undefined : getOpenApiUrl(),
    spec,
    deepLinking: true,
    displayOperationId: false,
    defaultModelsExpandDepth: 1,
    defaultModelExpandDepth: 1,
    docExpansion: 'list' as const,
    filter: true,
    showExtensions: true,
    showCommonExtensions: true,
    tryItOutEnabled: true,
    supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'] as ('get' | 'post' | 'put' | 'delete' | 'patch')[],
    requestInterceptor: (request: any) => {
      // Ajouter le token d'authentification si disponible
      const token = localStorage.getItem('access_token');
      if (token && request.headers) {
        request.headers['Authorization'] = `Bearer ${token}`;
      }
      // Ajouter le CSRF token si disponible
      const csrfToken = localStorage.getItem('csrf_token');
      if (csrfToken && request.headers) {
        request.headers['X-CSRF-Token'] = csrfToken;
      }
      return request;
    },
    onComplete: () => {
      setError(null);
      logger.debug('Swagger UI loaded successfully', {
        url: getOpenApiUrl(),
      });
    },
    onFailure: (err: Error) => {
      setError(err.message || 'Failed to load Swagger documentation');
      logger.error('Failed to load Swagger UI', {
        error: err.message,
        stack: err.stack,
        url: getOpenApiUrl(),
      });
    },
  };

  const handleRetry = () => {
    setError(null);
    // Force reload by updating the key
    window.location.reload();
  };

  // Si useIframe est true, utiliser un iframe pour charger Swagger UI HTML directement
  if (useIframe) {
    return (
      <div
        ref={containerRef}
        className="swagger-ui-container"
        style={{
          height: '100%',
          minHeight: '600px',
        }}
      >
        <iframe
          ref={iframeRef}
          src={getSwaggerUIUrl()}
          className="w-full h-full border-0 rounded-lg"
          style={{ minHeight: '600px' }}
          title="Swagger UI Documentation"
          onLoad={() => {
            logger.debug('Swagger UI iframe loaded successfully');
            setError(null);
          }}
          onError={() => {
            setError('Failed to load Swagger UI in iframe');
            logger.error('Failed to load Swagger UI iframe');
          }}
        />
      </div>
    );
  }

  if (error) {
    const swaggerUiUrl = getSwaggerUIUrl();
    return (
      <div className="flex flex-col items-center justify-center p-12 min-h-[600px]">
        <AlertCircle className="w-16 h-16 text-kodo-red mb-4" />
        <h3 className="text-xl font-bold text-white mb-2">
          Failed to Load API Documentation
        </h3>
        <p className="text-sm text-kodo-secondary mb-4 text-center max-w-md">
          {error}
        </p>
        <p className="text-xs text-kodo-content-dim mb-6 text-center max-w-md">
          Trying to load from: {getOpenApiUrl()}
          <br />
          <span className="text-kodo-steel">
            The Swagger JSON endpoint may not be available. Try opening Swagger UI directly.
          </span>
        </p>
        <div className="flex gap-4">
          <Button onClick={handleRetry} variant="default">
            <RefreshCw className="w-4 h-4 mr-2" />
            Retry
          </Button>
          <Button
            onClick={() => window.open(swaggerUiUrl, '_blank')}
            variant="outline"
          >
            Open Swagger UI
          </Button>
          <Button
            onClick={() => {
              // Basculer vers iframe mode
              window.location.reload();
            }}
            variant="outline"
          >
            Use Iframe Mode
          </Button>
        </div>
      </div>
    );
  }

  return (
    <div
      ref={containerRef}
      className="swagger-ui-container"
      style={{
        height: '100%',
        minHeight: '600px',
      }}
    >
      <style>{`
        .swagger-ui-container .swagger-ui {
          background: transparent;
        }
        .swagger-ui-container .swagger-ui .topbar {
          display: none;
        }
        .swagger-ui-container .swagger-ui .info {
          margin: 20px 0;
        }
        .swagger-ui-container .swagger-ui .info .title {
          color: #fff;
        }
        .swagger-ui-container .swagger-ui .scheme-container {
          background: rgba(255, 255, 255, 0.05);
          padding: 10px;
          border-radius: 8px;
          margin: 20px 0;
        }
        .swagger-ui-container .swagger-ui .opblock {
          background: rgba(255, 255, 255, 0.03);
          border: 1px solid rgba(255, 255, 255, 0.1);
          border-radius: 8px;
          margin: 10px 0;
        }
        .swagger-ui-container .swagger-ui .opblock.opblock-post {
          border-color: rgba(102, 252, 241, 0.3);
        }
        .swagger-ui-container .swagger-ui .opblock.opblock-get {
          border-color: rgba(102, 252, 241, 0.3);
        }
        .swagger-ui-container .swagger-ui .opblock.opblock-put {
          border-color: rgba(255, 193, 7, 0.3);
        }
        .swagger-ui-container .swagger-ui .opblock.opblock-delete {
          border-color: rgba(244, 67, 54, 0.3);
        }
        .swagger-ui-container .swagger-ui .opblock .opblock-summary {
          color: #fff;
        }
        .swagger-ui-container .swagger-ui .opblock .opblock-description-wrapper {
          color: rgba(255, 255, 255, 0.8);
        }
        .swagger-ui-container .swagger-ui .parameter__name {
          color: #66fcf1;
        }
        .swagger-ui-container .swagger-ui .response-col_status {
          color: #fff;
        }
        .swagger-ui-container .swagger-ui .response-col_description {
          color: rgba(255, 255, 255, 0.8);
        }
        .swagger-ui-container .swagger-ui input,
        .swagger-ui-container .swagger-ui select,
        .swagger-ui-container .swagger-ui textarea {
          background: rgba(255, 255, 255, 0.1);
          border: 1px solid rgba(255, 255, 255, 0.2);
          color: #fff;
        }
        .swagger-ui-container .swagger-ui .btn {
          background: #66fcf1;
          color: #000;
          border: none;
        }
        .swagger-ui-container .swagger-ui .btn:hover {
          background: #52e8e0;
        }
        .swagger-ui-container .swagger-ui .btn.execute {
          background: #66fcf1;
          color: #000;
        }
        .swagger-ui-container .swagger-ui .btn.cancel {
          background: rgba(255, 255, 255, 0.1);
          color: #fff;
        }
      `}</style>
      <SwaggerUI {...swaggerConfig} />
    </div>
  );
}
