import '@livekit/components-styles';

import {
  CarouselLayout,
  Chat,
  ControlBar,
  FocusLayout,
  FocusLayoutContainer,
  GridLayout,
  LayoutContextProvider,
  LiveKitRoom,
  ParticipantTile,
  RoomAudioRenderer,
  StartAudio,
  isTrackReference,
  useCreateLayoutContext,
  usePinnedTracks,
  useRoomContext,
  useTracks,
  ScreenShareIcon,
  ScreenShareStopIcon,
} from '@livekit/components-react';
import { RoomEvent, Track } from 'livekit-client';
import { useState, useEffect, useRef, useCallback } from 'react';
import { ScreenSourcePicker } from '@/components/screen-source-picker';
import { logError } from '@/lib/errors';

function readConnectionFromHash(): { token: string; serverUrl: string } | null {
  const params = new URLSearchParams(window.location.hash.slice(1));
  const token = params.get('token');
  const serverUrl = params.get('serverUrl');
  return token && serverUrl ? { token, serverUrl } : null;
}

export function HuddleApp() {
  const [connection] = useState(readConnectionFromHash);

  const handleDisconnected = () => {
    window.electronWindow.closeHuddle();
  };

  if (!connection) {
    return (
      <div className="flex h-screen items-center justify-center bg-background text-foreground">
        <p className="text-muted-foreground text-sm">Missing huddle connection data.</p>
      </div>
    );
  }

  return (
    <LiveKitRoom
      token={connection.token}
      serverUrl={connection.serverUrl}
      connect={true}
      audio={true}
      video={false}
      onDisconnected={handleDisconnected}
      data-lk-theme="default"
      style={{ height: '100vh' }}
    >
      <HuddleContent />
    </LiveKitRoom>
  );
}

function HuddleContent() {
  const room = useRoomContext();
  const [showPicker, setShowPicker] = useState(false);
  const [isSharing, setIsSharing] = useState(false);
  const [widgetState, setWidgetState] = useState({ showChat: false, unreadMessages: 0 });

  const tracks = useTracks(
    [
      { source: Track.Source.Camera, withPlaceholder: true },
      { source: Track.Source.ScreenShare, withPlaceholder: false },
    ],
    { updateOnlyOn: [RoomEvent.ActiveSpeakersChanged], onlySubscribed: false },
  );

  const layoutContext = useCreateLayoutContext();
  const screenShareTracks = tracks
    .filter(isTrackReference)
    .filter((t) => t.publication.source === Track.Source.ScreenShare);

  const pinnedTracks = usePinnedTracks(layoutContext);
  const focusTrack = pinnedTracks?.[0];
  const remainingTracks = tracks.filter(
    (t) =>
      !focusTrack ||
      t.participant.identity !== focusTrack.participant.identity ||
      t.source !== focusTrack.source,
  );

  // Auto-pin/unpin screen share tracks (same logic as VideoConference)
  const lastAutoPin = useRef<{ trackSid: string } | null>(null);
  useEffect(() => {
    if (
      screenShareTracks.some((t) => t.publication.isSubscribed) &&
      lastAutoPin.current === null
    ) {
      layoutContext.pin.dispatch?.({ msg: 'set_pin', trackReference: screenShareTracks[0] });
      lastAutoPin.current = { trackSid: screenShareTracks[0].publication.trackSid };
    } else if (
      lastAutoPin.current &&
      !screenShareTracks.some(
        (t) => t.publication.trackSid === lastAutoPin.current?.trackSid,
      )
    ) {
      layoutContext.pin.dispatch?.({ msg: 'clear_pin' });
      lastAutoPin.current = null;
    }
  }, [
    screenShareTracks.map((t) => `${t.publication.trackSid}_${t.publication.isSubscribed}`).join(),
  ]);

  // Sync isSharing state with actual track state
  useEffect(() => {
    const onLocalTrackUnpublished = () => {
      const pub = room.localParticipant.getTrackPublication(Track.Source.ScreenShare);
      if (!pub) setIsSharing(false);
    };
    room.on(RoomEvent.LocalTrackUnpublished, onLocalTrackUnpublished);
    return () => {
      room.off(RoomEvent.LocalTrackUnpublished, onLocalTrackUnpublished);
    };
  }, [room]);

  const handleScreenShare = useCallback(
    async (sourceId: string) => {
      setShowPicker(false);
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: false,
          video: {
            mandatory: {
              chromeMediaSource: 'desktop',
              chromeMediaSourceId: sourceId,
            },
          } as MediaTrackConstraints,
        });
        const videoTrack = stream.getVideoTracks()[0];
        await room.localParticipant.publishTrack(videoTrack, {
          source: Track.Source.ScreenShare,
        });
        setIsSharing(true);
        videoTrack.onended = () => stopScreenShare();
      } catch (err) {
        logError(err, { scope: "huddle.screenShare" });
      }
    },
    [room],
  );

  const stopScreenShare = useCallback(async () => {
    const pub = room.localParticipant.getTrackPublication(Track.Source.ScreenShare);
    if (pub?.track) {
      await room.localParticipant.unpublishTrack(pub.track.mediaStreamTrack);
      pub.track.stop();
    }
    setIsSharing(false);
  }, [room]);

  return (
    <div className="lk-video-conference">
      <LayoutContextProvider value={layoutContext} onWidgetChange={setWidgetState}>
        <div className="lk-video-conference-inner">
          {focusTrack ? (
            <div className="lk-focus-layout-wrapper">
              <FocusLayoutContainer>
                <CarouselLayout tracks={remainingTracks}>
                  <ParticipantTile />
                </CarouselLayout>
                <FocusLayout trackRef={focusTrack} />
              </FocusLayoutContainer>
            </div>
          ) : (
            <div className="lk-grid-layout-wrapper">
              <GridLayout tracks={tracks}>
                <ParticipantTile />
              </GridLayout>
            </div>
          )}
          <div className="lk-control-bar">
            <ControlBar
              controls={{ screenShare: false, chat: true }}
              style={{ border: 'none', padding: 0, maxHeight: 'none' }}
            />
            <button
              className="lk-button"
              onClick={isSharing ? stopScreenShare : () => setShowPicker(true)}
              aria-label={isSharing ? 'Stop sharing' : 'Share screen'}
            >
              {isSharing ? <ScreenShareStopIcon /> : <ScreenShareIcon />}
              {isSharing ? 'Stop share' : 'Share screen'}
            </button>
          </div>
        </div>
        <Chat style={{ display: widgetState.showChat ? 'grid' : 'none' }} />
      </LayoutContextProvider>
      <RoomAudioRenderer />
      <StartAudio label="Allow audio" />
      {showPicker && (
        <ScreenSourcePicker
          title="Share your screen"
          confirmLabel="Share"
          getSources={window.electronHuddle.getScreenSources}
          onSelect={handleScreenShare}
          onCancel={() => setShowPicker(false)}
        />
      )}
    </div>
  );
}
