import { useCoreServices } from '@learnitive/context';
import {
  Button,
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  Input,
  Label,
  toast,
} from '@learnitive/ui-components';
import { useAtomValue } from 'jotai';
import { Copy, LogIn, LogOut, Radio, Users } from 'lucide-react';
import QRCode from 'qrcode';
import React from 'react';
import { getAuthState, type SaasAuthState } from '../saas/saas-api';

export function CollaborationDialog({
  wsName,
  open,
  onOpenChange,
}: {
  wsName: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const { projectCollaboration, projectReview } = useCoreServices();
  const state = useAtomValue(projectCollaboration.$state);
  const [auth, setAuth] = React.useState<SaasAuthState>();
  const [busy, setBusy] = React.useState(false);
  const [qrDataUrl, setQrDataUrl] = React.useState<string>();
  const activeHere = state.active && state.wsName === wsName;

  React.useEffect(() => {
    if (!open || activeHere) return;
    let current = true;
    void getAuthState()
      .then((value) => { if (current) setAuth(value); })
      .catch(() => { if (current) setAuth({ authenticated: false }); });
    return () => { current = false; };
  }, [activeHere, open]);

  React.useEffect(() => {
    let cancelled = false;
    if (!activeHere || !state.isHost || !state.shareUrl) {
      setQrDataUrl(undefined);
      return () => { cancelled = true; };
    }
    void QRCode.toDataURL(state.shareUrl, {
      width: 200,
      margin: 2,
      color: { dark: '#000000', light: '#ffffff' },
    }).then((url) => {
      if (!cancelled) setQrDataUrl(url);
    }).catch((error) => {
      console.warn('[Learnitive] Unable to render collaboration QR code.', error);
      if (!cancelled) setQrDataUrl(undefined);
    });
    return () => { cancelled = true; };
  }, [activeHere, state.isHost, state.shareUrl]);

  const run = async (action: () => Promise<void>) => {
    setBusy(true);
    try {
      await action();
    } catch (error) {
      console.error('Collaboration action failed', error);
      toast.error(error instanceof Error ? error.message : 'Collaboration failed.');
    } finally {
      setBusy(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-h-[85vh] w-[calc(100vw-2rem)] max-w-xl overflow-x-hidden overflow-y-auto">
        <DialogHeader>
          <DialogTitle>Live collaboration</DialogTitle>
          <DialogDescription>
            Live collaboration synchronizes Source editing directly through Yjs. Comments and Track Changes are shared with collaborators.
          </DialogDescription>
        </DialogHeader>

        {activeHere ? (
          <div className="space-y-4">
            <div className="flex items-center gap-2 rounded border p-3 text-sm">
              <Radio className={`size-4 ${state.connectionPhase === 'live' ? 'text-emerald-500' : state.connectionPhase === 'reconnecting' ? 'text-amber-500' : 'text-muted-foreground'}`} />
              <div className="min-w-0 flex-1">
                <div className="font-medium capitalize">{state.connectionPhase}</div>
                {state.statusMessage ? <div className="truncate text-xs text-muted-foreground">{state.statusMessage}</div> : null}
              </div>
              <span className="text-muted-foreground">{state.isHost ? 'You are hosting' : 'Joined session'}</span>
            </div>

            {state.isHost && state.shareUrl ? (
              <div className="space-y-3">
                <Label>Project link</Label>
                <div className="flex min-w-0 gap-2">
                  <Input className="min-w-0 flex-1" readOnly value={state.shareUrl} />
                  <Button
                    aria-label="Copy project link"
                    className="shrink-0"
                    size="icon"
                    variant="outline"
                    onClick={() => {
                      void navigator.clipboard.writeText(state.shareUrl ?? '');
                      toast.success('Project link copied');
                    }}
                  >
                    <Copy className="size-4" />
                  </Button>
                </div>
                <p className="text-xs text-muted-foreground">Anyone with this live-session link is treated as a trusted editor while the host is available. Share it only with people you trust.</p>
                {qrDataUrl ? (
                  <div className="grid justify-items-center gap-2 rounded border p-3">
                    <img alt="QR code for the collaboration project link" className="size-[200px] max-w-full" src={qrDataUrl} />
                    <span className="text-xs text-muted-foreground">Scan to join this project</span>
                  </div>
                ) : null}
              </div>
            ) : null}

            <div className="space-y-2">
              <div className="flex items-center gap-2 font-medium text-sm">
                <Users className="size-4" />
                Collaborators ({state.peers.length + 1})
              </div>
              <div className="max-h-72 space-y-1 overflow-y-auto overflow-x-hidden rounded border p-2">
                <div className="flex min-w-0 items-center gap-2 rounded px-1 py-1 text-sm">
                  <span className="size-2 shrink-0 rounded-full" style={{ backgroundColor: state.userColor ?? '#10b981' }} />
                  <span className="min-w-0 flex-1 truncate font-medium">{state.userName ?? 'You'}</span>
                  <span className="shrink-0 text-xs text-muted-foreground">You</span>
                </div>
                {state.peers.map((peer) => (
                  <div className="flex min-w-0 items-center gap-2 rounded px-1 py-1 text-sm" key={peer.clientId}>
                    <span className="size-2 shrink-0 rounded-full" style={{ backgroundColor: peer.color }} />
                    <span className="min-w-0 flex-1 truncate font-medium" title={peer.name}>{peer.name}</span>
                  </div>
                ))}
                {state.peers.length === 0 ? <p className="px-1 py-1 text-xs text-muted-foreground">Waiting for collaborators…</p> : null}
              </div>
              <p className="text-xs text-muted-foreground">Remote caret, selection, name, and color are owned by the Source editor's Yjs binding.</p>
            </div>

            <div className="flex flex-wrap justify-end gap-2">
              <Button
                variant={state.isHost ? 'destructive' : 'outline'}
                disabled={busy}
                onClick={() => void run(async () => {
                  if (state.isHost) await projectCollaboration.stop();
                  else await projectCollaboration.leave({ forget: true, clearPersistence: true });
                  onOpenChange(false);
                })}
              >
                <LogOut className="mr-2 size-4" />
                {state.isHost ? 'Stop collaboration' : 'Leave collaboration'}
              </Button>
              <Button type="button" variant="outline" disabled={busy} onClick={() => onOpenChange(false)}>
                Close
              </Button>
            </div>
          </div>
        ) : (
          <div className="space-y-5">
            {!auth ? (
              <div className="rounded border p-3 text-sm text-muted-foreground">Checking your Learnitive account…</div>
            ) : !auth.authenticated ? (
              <div className="rounded border p-3">
                <p className="font-medium text-sm">Sign in to host live collaboration</p>
                <p className="mt-1 text-xs text-muted-foreground">Live collaboration hosting requires a signed-in Pro account. Every participant must sign in and be authorized for this project before joining.</p>
                <Button className="mt-3" onClick={() => { window.location.href = `/login?returnTo=${encodeURIComponent(window.location.pathname + window.location.hash)}`; }}>
                  <LogIn className="mr-1 size-4" />Sign in
                </Button>
              </div>
            ) : !auth.entitlement.pro ? (
              <div className="rounded border border-amber-300/60 bg-amber-50/60 p-3 dark:border-amber-700/60 dark:bg-amber-950/20">
                <p className="font-medium text-sm">Pro is required to start collaboration</p>
                <p className="mt-1 text-xs text-muted-foreground">
                  Signed-in Free users can join invited collaborations. Starting and hosting a new live session is a Pro feature.
                </p>
                <Button className="mt-3" variant="outline" render={<a href="/pricing" />}>
                  View Pro plans
                </Button>
              </div>
            ) : (
              <div className="rounded border p-3">
                <p className="font-medium text-sm">Start collaboration</p>
                <p className="mt-1 text-xs text-muted-foreground">
                  Learnitive will switch to Source mode and lock project structure for this live session. PDF compilation remains local and available.
                </p>
                <Button
                  className="mt-3"
                  disabled={busy}
                  onClick={() => void run(async () => {
                    if (projectReview.getTrackChangesEnabled(wsName)) {
                      const pending = projectReview.getChanges(wsName, { status: 'pending' });
                      if (pending.length > 0) {
                        throw new Error('Accept or reject pending local Track Changes before starting live collaboration.');
                      }
                    }
                    await projectCollaboration.start(wsName, {
                      userName: auth.user.displayName,
                      userId: String(auth.user.id),
                      username: auth.user.email,
                    });
                  })}
                >
                  Start collaboration
                </Button>
              </div>
            )}
            <p className="text-xs text-muted-foreground">To join another project, open the Project link shared by its host. <a className="underline underline-offset-2" href="/docs/collaboration">Collaboration guide</a></p>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
