'use client';

import { useEffect, useMemo, useRef, useState } from 'react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
  DialogFooter,
  DialogDescription,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { Share2, Clock, Users, Check } from 'lucide-react';
import { toast } from 'sonner';

interface ShareModalProps {
  analysisId: string;
}

interface DirectoryEntry {
  email: string;
  displayName: string | null;
  jobTitle: string | null;
  department: string | null;
}

interface RecentEntry {
  email: string;
  lastSharedAt: string;
}

interface RecipientsResponse {
  recent: RecentEntry[];
  directory: DirectoryEntry[];
  allowedDomains: string[];
}

const MAX_DIRECTORY_VISIBLE = 12;

function timeAgo(iso: string): string {
  const ms = Date.now() - new Date(iso).getTime();
  const minute = 60_000;
  const hour = 60 * minute;
  const day = 24 * hour;
  if (ms < hour) return `${Math.max(1, Math.round(ms / minute))}m ago`;
  if (ms < day) return `${Math.round(ms / hour)}h ago`;
  return `${Math.round(ms / day)}d ago`;
}

export function ShareModal({ analysisId }: ShareModalProps) {
  const [open, setOpen] = useState(false);
  const [recipientEmail, setRecipientEmail] = useState('');
  const [note, setNote] = useState('');
  const [submitting, setSubmitting] = useState(false);

  const [recipients, setRecipients] = useState<RecipientsResponse | null>(null);
  const [recipientsError, setRecipientsError] = useState<string | null>(null);
  const [showSuggestions, setShowSuggestions] = useState(false);

  const inputRef = useRef<HTMLInputElement>(null);

  // Fetch recipients lazily on first dialog open.
  useEffect(() => {
    if (!open) return;
    if (recipients !== null) return;
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch('/api/analyzer/share/recipients');
        if (!res.ok) {
          const data = (await res.json().catch(() => ({}))) as { error?: string };
          throw new Error(data.error ?? `Request failed: ${res.status}`);
        }
        const data = (await res.json()) as RecipientsResponse;
        if (!cancelled) setRecipients(data);
      } catch (err) {
        if (!cancelled) {
          setRecipientsError(
            err instanceof Error ? err.message : 'Unknown error'
          );
        }
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [open, recipients]);

  const filteredDirectory = useMemo(() => {
    if (!recipients) return [];
    const q = recipientEmail.trim().toLowerCase();
    if (!q) return recipients.directory.slice(0, MAX_DIRECTORY_VISIBLE);
    return recipients.directory
      .filter(
        (d) =>
          d.email.toLowerCase().includes(q) ||
          (d.displayName ?? '').toLowerCase().includes(q)
      )
      .slice(0, MAX_DIRECTORY_VISIBLE);
  }, [recipients, recipientEmail]);

  const hasRecent = (recipients?.recent.length ?? 0) > 0;

  function pick(email: string): void {
    setRecipientEmail(email);
    setShowSuggestions(false);
    inputRef.current?.blur();
  }

  async function handleSubmit(e: React.FormEvent): Promise<void> {
    e.preventDefault();
    setSubmitting(true);
    try {
      const res = await fetch(`/api/analyzer/analyses/${analysisId}/share`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          recipientEmail,
          note: note.trim() || undefined,
        }),
      });
      const data = (await res.json().catch(() => ({}))) as {
        error?: string;
        message?: string;
        emailSent?: boolean;
        emailError?: string | null;
      };
      if (!res.ok) {
        throw new Error(data.message ?? data.error ?? `Request failed: ${res.status}`);
      }
      if (data.emailSent === false) {
        toast.warning(
          `Share recorded for ${recipientEmail}, but email failed: ${data.emailError ?? 'unknown error'}`
        );
      } else {
        toast.success(`Shared with ${recipientEmail}`);
      }
      setOpen(false);
      setRecipientEmail('');
      setNote('');
    } catch (err) {
      const msg = err instanceof Error ? err.message : 'Unknown error';
      toast.error(msg);
    } finally {
      setSubmitting(false);
    }
  }

  // Reset transient state when the dialog closes.
  function onOpenChange(next: boolean): void {
    setOpen(next);
    if (!next) {
      setShowSuggestions(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogTrigger asChild>
        <Button variant="outline" size="sm">
          <Share2 className="w-4 h-4 mr-2" />
          Share
        </Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Share this analysis</DialogTitle>
          <DialogDescription>
            {recipients?.allowedDomains.length
              ? `Allowed domains: ${recipients.allowedDomains.join(', ')}`
              : 'Recipient must be on an allowed domain.'}
          </DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit} className="space-y-4">
          <div className="space-y-2">
            <Label htmlFor="recipient">Recipient</Label>
            <div className="relative">
              <Input
                id="recipient"
                ref={inputRef}
                type="email"
                required
                autoComplete="off"
                value={recipientEmail}
                onChange={(e) => {
                  setRecipientEmail(e.target.value);
                  setShowSuggestions(true);
                }}
                onFocus={() => setShowSuggestions(true)}
                onBlur={() => {
                  // Delay so a click on a suggestion lands before we hide.
                  setTimeout(() => setShowSuggestions(false), 150);
                }}
                placeholder="Search teammates or type an email…"
              />

              {showSuggestions && recipients !== null && (
                <div className="absolute z-50 mt-1 w-full rounded-md border bg-popover shadow-md max-h-72 overflow-auto">
                  {hasRecent && recipientEmail.trim().length === 0 && (
                    <div className="px-2 py-1.5 text-xs font-semibold text-muted-foreground flex items-center gap-1">
                      <Clock className="w-3 h-3" /> Recent
                    </div>
                  )}
                  {hasRecent &&
                    recipientEmail.trim().length === 0 &&
                    recipients.recent.slice(0, 3).map((r) => (
                      <button
                        key={'recent-' + r.email}
                        type="button"
                        className="w-full text-left px-3 py-2 text-sm hover:bg-accent flex items-center justify-between gap-2"
                        onMouseDown={(e) => {
                          e.preventDefault();
                          pick(r.email);
                        }}
                      >
                        <span className="truncate">{r.email}</span>
                        <span className="text-xs text-muted-foreground shrink-0">
                          {timeAgo(r.lastSharedAt)}
                        </span>
                      </button>
                    ))}

                  <div className="px-2 py-1.5 text-xs font-semibold text-muted-foreground flex items-center gap-1 border-t">
                    <Users className="w-3 h-3" /> Directory
                  </div>
                  {filteredDirectory.length === 0 ? (
                    <div className="px-3 py-2 text-sm text-muted-foreground">
                      No matching directory users.
                    </div>
                  ) : (
                    filteredDirectory.map((d) => (
                      <button
                        key={'dir-' + d.email}
                        type="button"
                        className="w-full text-left px-3 py-2 text-sm hover:bg-accent flex items-start justify-between gap-2"
                        onMouseDown={(e) => {
                          e.preventDefault();
                          pick(d.email);
                        }}
                      >
                        <div className="min-w-0 flex-1">
                          <div className="truncate font-medium">
                            {d.displayName ?? d.email}
                          </div>
                          {d.displayName && (
                            <div className="truncate text-xs text-muted-foreground">
                              {d.email}
                              {d.jobTitle ? ` · ${d.jobTitle}` : ''}
                            </div>
                          )}
                        </div>
                        {recipientEmail === d.email && (
                          <Check className="w-4 h-4 shrink-0 text-primary" />
                        )}
                      </button>
                    ))
                  )}
                </div>
              )}
            </div>
            {recipientsError && (
              <p className="text-xs text-muted-foreground">
                Couldn&rsquo;t load directory ({recipientsError}). Type any
                allowed-domain email to share.
              </p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="note">Note (optional)</Label>
            <Textarea
              id="note"
              value={note}
              onChange={(e) => setNote(e.target.value)}
              placeholder="Why you're sharing this…"
              rows={3}
              maxLength={2000}
            />
          </div>

          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => setOpen(false)}
              disabled={submitting}
            >
              Cancel
            </Button>
            <Button type="submit" disabled={submitting || !recipientEmail}>
              {submitting ? 'Sharing…' : 'Share'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
