/* eslint-disable @typescript-eslint/no-explicit-any */
import type { UserData } from '../App';
import { getPlatformConfig } from './config';

const generateCodeVerifier = () => {
  const array = new Uint8Array(32);
  window.crypto.getRandomValues(array);
  return btoa(String.fromCharCode(...array))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
};

const generateCodeChallenge = async (verifier: string) => {
  const encoder = new TextEncoder();
  const data = encoder.encode(verifier);
  const digest = await window.crypto.subtle.digest('SHA-256', data);
  return btoa(String.fromCharCode(...new Uint8Array(digest)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
};

const twitterLogin = async (): Promise<UserData> => {
  const config = getPlatformConfig('x');
  if (!config.enabled || !config.key || !config.secret) {
    throw new Error('X (Twitter) is not configured or disabled');
  }

  const clientId = config.key;
  const clientSecret = config.secret;
  const redirectUri = `${window.location.origin}/apps/auth/callback?shop=${window.location.origin}&platform=x`;
  console.log('X(Twitter)ログイン - リダイレクトURL:', redirectUri);
  
  const codeVerifier = generateCodeVerifier();
  const codeChallenge = await generateCodeChallenge(codeVerifier);
  const state = window.crypto.randomUUID();
  const scope = 'tweet.read users.read offline.access';

  const authUrl =
    `https://twitter.com/i/oauth2/authorize?response_type=code` +
    `&client_id=${clientId}` +
    `&redirect_uri=${encodeURIComponent(redirectUri)}` +
    `&scope=${encodeURIComponent(scope)}` +
    `&state=${state}` +
    `&code_challenge=${codeChallenge}` +
    `&code_challenge_method=S256`;

  const width = 600;
  const height = 700;
  const left = window.screenX + (window.outerWidth - width) / 2;
  const top = window.screenY + (window.outerHeight - height) / 2;

  const authWindow = window.open(
    authUrl,
    'twitterLogin',
    `width=${width},height=${height},left=${left},top=${top}`
  );

  return new Promise((resolve, reject) => {
    const handleMessage = async (event: MessageEvent<any>) => {
      if (event.origin !== window.location.origin) return;
      const { code, state: returnedState, error } = event.data || {};
      if (returnedState !== state) return;

      window.removeEventListener('message', handleMessage);
      authWindow?.close();

      if (code) {
        try {
          const tokenResponse = await fetch('https://api.twitter.com/2/oauth2/token', {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
              client_id: clientId,
              client_secret: clientSecret,
              code: code as string,
              grant_type: 'authorization_code',
              redirect_uri: redirectUri,
              code_verifier: codeVerifier
            })
          }).then(res => res.json());

          const accessToken = tokenResponse.access_token;
          const userInfo = await fetch(
            'https://api.twitter.com/2/users/me?user.fields=profile_image_url,name',
            { headers: { Authorization: `Bearer ${accessToken}` } }
          ).then(res => res.json());

          const user: UserData = {
            name: userInfo.data?.name ?? '',
            email: userInfo.data?.email ?? '',
            birthday: '',
            profileImage: userInfo.data?.profile_image_url ?? '',
            platform: 'x'
          };
          resolve(user);
        } catch (err) {
          reject(err);
        }
      } else {
        reject(new Error(error || 'Twitter login failed'));
      }
    };

    window.addEventListener('message', handleMessage);
  });
};

export default twitterLogin;

