"use client";

import { GraphQLClient, gql } from "graphql-request";
import Image from "next/image";
import { useEffect, useState } from "react";

const GET_CONNECTORS_QUERY = gql`
  query GetConnectors {
    connectors {
      success
      message
      connectors {
        id
        type
        enabled
        config
        metadata {
          id
          target
          platform
          name
          description
          logo
          logoDark
        }
        createdAt
        updatedAt
      }
      availableConnectors {
        id
        target
        platform
        name
        description
        logo
        logoDark
        configTemplate
        formItems {
          key
          type
          label
          placeholder
          required
          defaultValue
          description
        }
        isAdded
      }
    }
  }
`;

const CREATE_CONNECTOR_MUTATION = gql`
  mutation CreateConnector($input: CreateConnectorInput!) {
    createConnector(input: $input) {
      success
      message
      connector {
        id
        type
        enabled
        metadata {
          name
          platform
        }
      }
    }
  }
`;

const UPDATE_CONNECTOR_MUTATION = gql`
  mutation UpdateConnector($input: UpdateConnectorInput!) {
    updateConnector(input: $input) {
      success
      message
      connector {
        id
        enabled
      }
    }
  }
`;

const DELETE_CONNECTOR_MUTATION = gql`
  mutation DeleteConnector($id: ID!) {
    deleteConnector(id: $id) {
      success
      message
    }
  }
`;

const TOGGLE_CONNECTOR_MUTATION = gql`
  mutation ToggleConnector($id: ID!, $enabled: Boolean!) {
    toggleConnector(id: $id, enabled: $enabled) {
      success
      message
      connector {
        id
        enabled
      }
    }
  }
`;

const TEST_CONNECTOR_MUTATION = gql`
  mutation TestConnector($id: ID!) {
    testConnector(id: $id) {
      success
      message
    }
  }
`;

interface Connector {
  id: string;
  type: string;
  enabled: boolean;
  config: Record<string, unknown>;
  metadata: {
    id: string;
    target: string;
    platform?: string;
    name: string | Record<string, string>;
    description: string | Record<string, string>;
    logo: string;
    logoDark: string | null;
  };
  createdAt: string;
  updatedAt: string;
}

interface FactoryConnector {
  id: string;
  target: string;
  platform?: string;
  name: string | Record<string, string>;
  description: string | Record<string, string>;
  logo: string;
  logoDark: string | null;
  configTemplate: Record<string, unknown> | null;
  formItems: FormItem[];
  isAdded: boolean;
}

interface FormItem {
  key: string;
  type: string;
  label: string | Record<string, string>;
  placeholder?: string | Record<string, string>;
  required?: boolean;
  defaultValue?: string | boolean | number | string[];
  description?: string | Record<string, string>;
}

interface ConnectorsResponse {
  connectors: {
    success: boolean;
    message?: string;
    connectors?: Connector[];
    availableConnectors?: FactoryConnector[];
  };
}

export default function ConnectorsPage() {
  const [connectors, setConnectors] = useState<Connector[]>([]);
  const [availableConnectors, setAvailableConnectors] = useState<FactoryConnector[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [selectedFactory, setSelectedFactory] = useState<FactoryConnector | null>(null);
  const [showConfig, setShowConfig] = useState(false);
  const [configForm, setConfigForm] = useState<Record<string, string | boolean | number | string[]>>({});

  useEffect(() => {
    fetchConnectors();
  }, []);

  const fetchConnectors = async () => {
    setLoading(true);
    setError(null);

    try {
      const storedToken = localStorage.getItem("accessToken");
      if (!storedToken) {
        setError("Aucun token trouvé. Veuillez vous connecter.");
        return;
      }

      const authenticatedClient = new GraphQLClient(process.env.NEXT_PUBLIC_APP_URL + "/api/graphql", {
        headers: {
          Authorization: `Bearer ${storedToken}`,
        },
      });

      const response = await authenticatedClient.request<ConnectorsResponse>(GET_CONNECTORS_QUERY);

      if (response.connectors.success) {
        setConnectors(response.connectors.connectors || []);
        setAvailableConnectors(response.connectors.availableConnectors || []);
      } else {
        setError(response.connectors.message || "Erreur lors du chargement");
      }
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : "Une erreur est survenue";
      setError(errorMessage);
      console.error("Erreur lors du chargement des connecteurs:", err);
    } finally {
      setLoading(false);
    }
  };

  const handleCreateConnector = async () => {
    if (!selectedFactory) return;

    try {
      const storedToken = localStorage.getItem("accessToken");
      if (!storedToken) {
        setError("Aucun token trouvé. Veuillez vous connecter.");
        return;
      }

      const authenticatedClient = new GraphQLClient(process.env.NEXT_PUBLIC_APP_URL + "/api/graphql", {
        headers: {
          Authorization: `Bearer ${storedToken}`,
        },
      });

      const response = (await authenticatedClient.request(CREATE_CONNECTOR_MUTATION, {
        input: {
          connectorId: selectedFactory.id,
          config: configForm,
        },
      })) as {
        createConnector: {
          success: boolean;
          message?: string;
          connector?: {
            id: string;
            enabled: boolean;
            metadata: {
              name: string | Record<string, string>;
              platform?: string;
            };
          };
        };
      };

      if (response.createConnector.success) {
        await fetchConnectors();
        setShowConfig(false);
        setSelectedFactory(null);
        setConfigForm({});
      } else {
        setError(response.createConnector.message || "Erreur lors de la création");
      }
    } catch (err: unknown) {
      const errorMessage = err instanceof Error ? err.message : "Une erreur est survenue";
      setError(errorMessage);
    }
  };

  const handleToggleConnector = async (id: string, enabled: boolean) => {
    try {
      const storedToken = localStorage.getItem("accessToken");
      if (!storedToken) return;

      const authenticatedClient = new GraphQLClient(process.env.NEXT_PUBLIC_APP_URL + "/api/graphql", {
        headers: {
          Authorization: `Bearer ${storedToken}`,
        },
      });

      await authenticatedClient.request(TOGGLE_CONNECTOR_MUTATION, {
        id,
        enabled,
      });

      await fetchConnectors();
    } catch (err: unknown) {
      console.error("Erreur lors du basculement:", err);
    }
  };

  const handleDeleteConnector = async (id: string) => {
    if (!confirm("Êtes-vous sûr de vouloir supprimer ce connecteur ?")) return;

    try {
      const storedToken = localStorage.getItem("accessToken");
      if (!storedToken) return;

      const authenticatedClient = new GraphQLClient(process.env.NEXT_PUBLIC_APP_URL + "/api/graphql", {
        headers: {
          Authorization: `Bearer ${storedToken}`,
        },
      });

      await authenticatedClient.request(DELETE_CONNECTOR_MUTATION, { id });
      await fetchConnectors();
    } catch (err: unknown) {
      console.error("Erreur lors de la suppression:", err);
    }
  };

  const handleTestConnector = async (id: string) => {
    try {
      const storedToken = localStorage.getItem("accessToken");
      if (!storedToken) return;

      const authenticatedClient = new GraphQLClient(process.env.NEXT_PUBLIC_APP_URL + "/api/graphql", {
        headers: {
          Authorization: `Bearer ${storedToken}`,
        },
      });

      const response = (await authenticatedClient.request(TEST_CONNECTOR_MUTATION, { id })) as {
        testConnector: {
          success: boolean;
          message?: string;
        };
      };
      alert(response.testConnector.message || "Test terminé");
    } catch (err: unknown) {
      console.error("Erreur lors du test:", err);
    }
  };

  const openConfigDialog = (factory: FactoryConnector) => {
    setSelectedFactory(factory);
    setShowConfig(true);
    // Initialiser le formulaire avec les valeurs par défaut
    const initialForm: Record<string, string | boolean | number | string[]> = {};
    factory.formItems.forEach(item => {
      if (item.defaultValue !== undefined) {
        initialForm[item.key] = item.defaultValue;
      }
    });
    setConfigForm(initialForm);
  };

  const getConnectorName = (nameObj: string | Record<string, string>): string => {
    if (typeof nameObj === "object" && nameObj !== null) {
      return nameObj.en || nameObj.fr || Object.values(nameObj)[0] || "Connecteur";
    }
    return nameObj || "Connecteur";
  };

  const getConnectorDescription = (descObj: string | Record<string, string>): string => {
    if (typeof descObj === "object" && descObj !== null) {
      return descObj.en || descObj.fr || Object.values(descObj)[0] || "";
    }
    return descObj || "";
  };

  return (
    <div className="min-h-screen bg-gray-50 px-4 py-12 sm:px-6 lg:px-8">
      <div className="mx-auto max-w-6xl">
        <div className="rounded-lg bg-white p-8 shadow-lg">
          <h1 className="mb-6 text-center text-2xl font-bold text-gray-900">Gestion des Connecteurs Logto</h1>

          {error && (
            <div className="mb-6 rounded-md border border-red-200 bg-red-50 p-4">
              <p className="text-sm text-red-700">{error}</p>
            </div>
          )}

          {loading ? (
            <div className="text-center">
              <p>Chargement des connecteurs...</p>
            </div>
          ) : (
            <div className="space-y-8">
              {/* Connecteurs configurés */}
              <div>
                <h2 className="mb-4 text-xl font-semibold text-gray-800">
                  Connecteurs configurés ({connectors.length})
                </h2>

                {connectors.length === 0 ? (
                  <p className="text-gray-500">Aucun connecteur configuré</p>
                ) : (
                  <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
                    {connectors.map(connector => (
                      <div key={connector.id} className="rounded-lg border border-gray-200 bg-white p-4 shadow-sm">
                        <div className="flex items-center justify-between">
                          <Image
                            src={connector.metadata.logo}
                            alt={getConnectorName(connector.metadata.name)}
                            width={32}
                            height={32}
                            className="h-8 w-8"
                          />
                          <span
                            className={`rounded-full px-2 py-1 text-xs ${
                              connector.enabled ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"
                            }`}
                          >
                            {connector.enabled ? "Activé" : "Désactivé"}
                          </span>
                        </div>

                        <h3 className="mt-2 font-medium text-gray-900">{getConnectorName(connector.metadata.name)}</h3>

                        <p className="text-sm text-gray-600">{connector.metadata.platform || connector.type}</p>

                        <div className="mt-4 flex space-x-2">
                          <button
                            onClick={() => handleToggleConnector(connector.id, !connector.enabled)}
                            className={`rounded px-3 py-1 text-xs ${
                              connector.enabled
                                ? "bg-red-100 text-red-700 hover:bg-red-200"
                                : "bg-green-100 text-green-700 hover:bg-green-200"
                            }`}
                          >
                            {connector.enabled ? "Désactiver" : "Activer"}
                          </button>

                          <button
                            onClick={() => handleTestConnector(connector.id)}
                            className="rounded bg-blue-100 px-3 py-1 text-xs text-blue-700 hover:bg-blue-200"
                          >
                            Tester
                          </button>

                          <button
                            onClick={() => handleDeleteConnector(connector.id)}
                            className="rounded bg-red-100 px-3 py-1 text-xs text-red-700 hover:bg-red-200"
                          >
                            Supprimer
                          </button>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>

              {/* Connecteurs disponibles */}
              <div>
                <h2 className="mb-4 text-xl font-semibold text-gray-800">Connecteurs disponibles</h2>

                <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
                  {availableConnectors.map(factory => (
                    <div
                      key={factory.id}
                      className={`rounded-lg border p-4 shadow-sm ${
                        factory.isAdded ? "border-gray-300 bg-gray-50" : "border-gray-200 bg-white"
                      }`}
                    >
                      <div className="flex items-center justify-between">
                        <Image
                          src={factory.logo}
                          alt={getConnectorName(factory.name)}
                          width={32}
                          height={32}
                          className="h-8 w-8"
                        />
                        {factory.isAdded && (
                          <span className="rounded-full bg-green-100 px-2 py-1 text-xs text-green-800">Ajouté</span>
                        )}
                      </div>

                      <h3 className="mt-2 font-medium text-gray-900">{getConnectorName(factory.name)}</h3>

                      <p className="text-sm text-gray-600">{getConnectorDescription(factory.description)}</p>

                      {!factory.isAdded && (
                        <button
                          onClick={() => openConfigDialog(factory)}
                          className="mt-4 w-full rounded bg-blue-600 px-4 py-2 text-sm text-white hover:bg-blue-700"
                        >
                          Configurer
                        </button>
                      )}
                    </div>
                  ))}
                </div>
              </div>
            </div>
          )}

          {/* Dialog de configuration */}
          {showConfig && selectedFactory && (
            <div className="bg-opacity-50 fixed inset-0 z-50 flex items-center justify-center bg-black">
              <div className="max-h-[80vh] w-full max-w-md overflow-y-auto rounded-lg bg-white p-6">
                <div className="mb-4 flex items-center justify-between">
                  <h3 className="text-lg font-medium">Configurer {getConnectorName(selectedFactory.name)}</h3>
                  <button onClick={() => setShowConfig(false)} className="text-gray-400 hover:text-gray-600">
                    ✕
                  </button>
                </div>

                <form
                  onSubmit={e => {
                    e.preventDefault();
                    handleCreateConnector();
                  }}
                  className="space-y-4"
                >
                  {selectedFactory.formItems.map(item => (
                    <div key={item.key}>
                      <label className="block text-sm font-medium text-gray-700">
                        {typeof item.label === "object" && item.label !== null
                          ? item.label.en || item.label.fr
                          : item.label}
                        {item.required && <span className="text-red-500">*</span>}
                      </label>

                      {item.type === "Password" ? (
                        <input
                          type="password"
                          required={item.required}
                          value={String(configForm[item.key] || "")}
                          onChange={e => setConfigForm({ ...configForm, [item.key]: e.target.value })}
                          className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                        />
                      ) : item.type === "Switch" ? (
                        <input
                          type="checkbox"
                          checked={Boolean(configForm[item.key])}
                          onChange={e => setConfigForm({ ...configForm, [item.key]: e.target.checked })}
                          className="mt-1"
                        />
                      ) : item.type === "MultiSelect" ? (
                        <select
                          multiple
                          required={item.required}
                          value={Array.isArray(configForm[item.key]) ? (configForm[item.key] as string[]) : []}
                          onChange={e => {
                            const values = Array.from(e.target.selectedOptions, option => option.value);
                            setConfigForm({ ...configForm, [item.key]: values });
                          }}
                          className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                        >
                          {/* Options would come from the form item configuration */}
                        </select>
                      ) : item.type === "Number" ? (
                        <input
                          type="number"
                          required={item.required}
                          value={Number(configForm[item.key] || 0)}
                          onChange={e => setConfigForm({ ...configForm, [item.key]: Number(e.target.value) })}
                          placeholder={
                            typeof item.placeholder === "object" && item.placeholder !== null
                              ? item.placeholder.en || item.placeholder.fr
                              : item.placeholder || ""
                          }
                          className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                        />
                      ) : (
                        <input
                          type="text"
                          required={item.required}
                          value={String(configForm[item.key] || "")}
                          onChange={e => setConfigForm({ ...configForm, [item.key]: e.target.value })}
                          placeholder={
                            typeof item.placeholder === "object" && item.placeholder !== null
                              ? item.placeholder.en || item.placeholder.fr
                              : item.placeholder || ""
                          }
                          className="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:ring-blue-500"
                        />
                      )}

                      {item.description && (
                        <p className="mt-1 text-xs text-gray-500">
                          {typeof item.description === "object" && item.description !== null
                            ? item.description.en || item.description.fr
                            : item.description}
                        </p>
                      )}
                    </div>
                  ))}

                  <div className="flex space-x-4 pt-4">
                    <button type="submit" className="flex-1 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700">
                      Créer
                    </button>
                    <button
                      type="button"
                      onClick={() => setShowConfig(false)}
                      className="flex-1 rounded border border-gray-300 px-4 py-2 text-gray-700 hover:bg-gray-50"
                    >
                      Annuler
                    </button>
                  </div>
                </form>
              </div>
            </div>
          )}

          {/* Navigation */}
          <div className="mt-8 rounded-md border border-blue-200 bg-blue-50 p-4">
            <h3 className="text-sm font-medium text-blue-800">Navigation</h3>
            <div className="mt-2 space-y-1">
              <div>
                <a href="/login" className="text-sm text-blue-600 underline hover:text-blue-500">
                  🔐 Page de connexion
                </a>
              </div>
              <div>
                <a href="/signup" className="text-sm text-blue-600 underline hover:text-blue-500">
                  📝 Page d&apos;inscription
                </a>
              </div>
              <div>
                <a href="/profile" className="text-sm text-blue-600 underline hover:text-blue-500">
                  👤 Voir votre profil
                </a>
              </div>
              <div>
                <a href="/test-users" className="text-sm text-blue-600 underline hover:text-blue-500">
                  👥 Liste des utilisateurs
                </a>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
