import { Avatar, AvatarImage, Box, Button, Text } from 'folds';
import { IIdentityProvider, SSOAction, createClient } from 'matrix-js-sdk';
import React, { useCallback, useMemo, useState } from 'react';
import { useAutoDiscoveryInfo } from '../../hooks/useAutoDiscoveryInfo';
import { openExternalUrl } from '../../utils/tauri';

type SSOLoginProps = {
  providers?: IIdentityProvider[];
  redirectUrl: string;
  action?: SSOAction;
  saveScreenSpace?: boolean;
};
export function SSOLogin({ providers, redirectUrl, action, saveScreenSpace }: SSOLoginProps) {
  const discovery = useAutoDiscoveryInfo();
  const baseUrl = discovery['m.homeserver'].base_url;
  const mx = useMemo(() => createClient({ baseUrl }), [baseUrl]);
  const [launchingProviderId, setLaunchingProviderId] = useState<string | null>(null);

  const getSSOIdUrl = (ssoId?: string): string => {
    const existingDeviceId = localStorage.getItem('cinny_device_id') ?? undefined;
    return mx.getSsoLoginUrl(redirectUrl, 'sso', ssoId, action, existingDeviceId);
  };

  const handleContinue = useCallback(
    async (providerId?: string) => {
      if (launchingProviderId) {
        return;
      }

      const currentProviderId = providerId ?? '__default__';
      setLaunchingProviderId(currentProviderId);

      try {
        if (window.electron?.protocol?.repair) {
          await window.electron.protocol.repair();
        }
      } catch (error) {
        console.warn('[SSOLogin] Protocol repair failed before SSO launch:', error);
      }

      try {
        await openExternalUrl(getSSOIdUrl(providerId));
      } finally {
        setLaunchingProviderId(null);
      }
    },
    [getSSOIdUrl, launchingProviderId]
  );

  const withoutIcon = providers
    ? providers.find(
        (provider) => !provider.icon || !mx.mxcUrlToHttp(provider.icon, 96, 96, 'crop', false)
      )
    : true;

  const renderAsIcons = withoutIcon ? false : saveScreenSpace && providers && providers.length > 2;

  return (
    <Box justifyContent="Center" gap="600" wrap="Wrap">
      {providers ? (
        providers.map((provider) => {
          const { id, name, icon } = provider;
          const iconUrl = icon && mx.mxcUrlToHttp(icon, 96, 96, 'crop', false);

          const buttonTitle = `Continue with ${name}`;

          if (renderAsIcons) {
            return (
              <Avatar
                style={{ cursor: 'pointer' }}
                key={id}
                as="button"
                aria-label={buttonTitle}
                size="300"
                radii="300"
                onClick={() => {
                  handleContinue(id);
                }}
              >
                <AvatarImage src={iconUrl!} alt={name} title={buttonTitle} />
              </Avatar>
            );
          }

          return (
            <Button
              style={{ width: '100%' }}
              key={id}
              size="500"
              variant="Secondary"
              fill="Soft"
              outlined
              disabled={Boolean(launchingProviderId)}
              onClick={() => {
                handleContinue(id);
              }}
              before={
                iconUrl && (
                  <Avatar size="200" radii="300">
                    <AvatarImage src={iconUrl} alt={name} />
                  </Avatar>
                )
              }
            >
              <Text align="Center" size="B500" truncate>
                {buttonTitle}
              </Text>
            </Button>
          );
        })
      ) : (
        <Button
          style={{ width: '100%' }}
          size="500"
          variant="Secondary"
          fill="Soft"
          outlined
          disabled={Boolean(launchingProviderId)}
          onClick={() => {
            handleContinue();
          }}
        >
          <Text align="Center" size="B500" truncate>
            Continue with SSO
          </Text>
        </Button>
      )}
    </Box>
  );
}
