'use client';

import { useEffect, useMemo, useRef, useState } from 'react';

type PermissionState = 'granted' | 'denied' | 'prompt';

type BackgroundModePlugin = {
  checkMicrophonePermission: () => Promise<{ microphone: PermissionState | string }>;
  requestMicrophonePermission: () => Promise<{ microphone: PermissionState | string }>;
  checkNotificationsPermission: () => Promise<{ notifications: PermissionState | string }>;
  requestNotificationsPermission: () => Promise<{ notifications: PermissionState | string }>;
  checkBatteryOptimizations: () => Promise<{ enabled: boolean }>;
  requestDisableBatteryOptimizations: () => Promise<void>;
  disableWebViewOptimizations: () => Promise<void>;
  enable: (options: {
    title: string;
    text: string;
    channelName: string;
    channelDescription: string;
    resume: boolean;
    silent: boolean;
    disableWebViewOptimization: boolean;
  }) => Promise<void>;
  addListener: (eventName: string, listener: () => void) => Promise<void>;
};

type CapacitorRuntime = {
  Plugins?: {
    BackgroundMode?: BackgroundModePlugin;
  };
};

type CapacitorWindow = Window & {
  Capacitor?: CapacitorRuntime;
};

const STREAM_URL = 'https://kryz.out.airtime.pro/kryz_b';

export default function HomePage() {
  const audioRef = useRef<HTMLAudioElement | null>(null);
  const [status, setStatus] = useState('Stream is stopped.');
  const [isPlaying, setIsPlaying] = useState(false);

  const backgroundMode = useMemo(() => {
    if (typeof window === 'undefined') {
      return undefined;
    }
    return (window as CapacitorWindow).Capacitor?.Plugins?.BackgroundMode;
  }, []);

  useEffect(() => {
    const audio = audioRef.current;
    if (!audio) {
      return;
    }

    const handleEnded = () => {
      setIsPlaying(false);
      setStatus('Stream ended.');
    };

    const handleError = () => {
      setIsPlaying(false);
      setStatus('Stream error.');
    };

    audio.addEventListener('ended', handleEnded);
    audio.addEventListener('error', handleError);

    return () => {
      audio.removeEventListener('ended', handleEnded);
      audio.removeEventListener('error', handleError);
    };
  }, []);

  useEffect(() => {
    if (!backgroundMode) {
      console.warn('BackgroundMode plugin is not available in this runtime.');
      return;
    }

    const initializeBackgroundMode = async () => {
      try {
        const notificationPermission = await backgroundMode.checkNotificationsPermission();
        if (notificationPermission.notifications !== 'granted') {
          await backgroundMode.requestNotificationsPermission();
        }

        const microphonePermission = await backgroundMode.checkMicrophonePermission();
        if (microphonePermission.microphone !== 'granted') {
          const requestedMicrophonePermission = await backgroundMode.requestMicrophonePermission();
          if (requestedMicrophonePermission.microphone !== 'granted') {
            console.warn(
              'BackgroundMode microphone permission denied; background playback may stop when screen is off.'
            );
          }
        }

        const batteryOptimizations = await backgroundMode.checkBatteryOptimizations();
        if (batteryOptimizations.enabled) {
          console.warn(
            'Battery optimizations are enabled; requesting exemption for reliable background playback.'
          );
          await backgroundMode.requestDisableBatteryOptimizations();
        }

        await backgroundMode.disableWebViewOptimizations();

        await backgroundMode.enable({
          title: 'KRYZ-Go!',
          text: 'Background mode is active',
          channelName: 'kryz-go background',
          channelDescription: 'Keeps kryz-go running while the app is in background',
          resume: true,
          silent: false,
          disableWebViewOptimization: true,
        });

        await backgroundMode.addListener('appInBackground', () => {
          console.log('kryz-go moved to background');
        });

        await backgroundMode.addListener('appInForeground', () => {
          console.log('kryz-go returned to foreground');
        });

        console.log('BackgroundMode plugin enabled.');
      } catch (error) {
        console.error('Failed to initialize BackgroundMode plugin:', error);
      }
    };

    void initializeBackgroundMode();
  }, [backgroundMode]);

  const ensureBackgroundPlaybackPermissions = async () => {
    if (!backgroundMode) {
      return true;
    }

    const microphonePermission = await backgroundMode.checkMicrophonePermission();
    if (microphonePermission.microphone === 'granted') {
      return true;
    }

    const requestedMicrophonePermission = await backgroundMode.requestMicrophonePermission();
    if (requestedMicrophonePermission.microphone === 'granted') {
      return true;
    }

    setStatus('Enable microphone permission in Android settings for screen-off playback.');
    console.warn('Background playback blocked: microphone permission not granted.');
    return false;
  };

  const startStream = async () => {
    const audio = audioRef.current;
    if (!audio) {
      return;
    }

    try {
      const hasBackgroundPermissions = await ensureBackgroundPlaybackPermissions();
      if (!hasBackgroundPermissions) {
        return;
      }

      audio.src = STREAM_URL;
      await audio.play();
      setIsPlaying(true);
      setStatus('Stream is playing.');
    } catch (error) {
      setIsPlaying(false);
      setStatus('Unable to start stream.');
      console.error('Failed to start stream:', error);
    }
  };

  const stopStream = () => {
    const audio = audioRef.current;
    if (!audio) {
      return;
    }

    audio.pause();
    audio.removeAttribute('src');
    audio.load();

    setIsPlaying(false);
    setStatus('Stream is stopped.');
  };

  return (
    <main className="page-shell">
      <section className="player-card" aria-label="KRYZ live stream player">
        <p className="eyebrow">KRYZ Go!</p>
        <h1>Live Radio</h1>
        <p className="status" aria-live="polite">
          {status}
        </p>

        <div className="controls">
          <button type="button" onClick={startStream} disabled={isPlaying}>
            Start Stream
          </button>
          <button type="button" onClick={stopStream} disabled={!isPlaying}>
            Stop Stream
          </button>
        </div>

        <audio ref={audioRef} preload="none" />
      </section>
    </main>
  );
}
