import { useRef, useState } from "react";
import { QRCodeSVG } from "qrcode.react";
import { sendCloud } from "../lib/sendCloud";
import { useProfileStore } from "../stores/useProfileStore";

type Stage =
  | { kind: "idle" }
  | { kind: "uploading"; loaded: number; total: number }
  | { kind: "done"; shareUrl: string; fileName: string; expiresAt: string; password: string | null }
  | { kind: "error"; message: string };

const EXPIRY_CHOICES: { label: string; days: number }[] = [
  { label: "1 day", days: 1 },
  { label: "7 days", days: 7 },
  { label: "30 days", days: 30 },
];

function formatSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
}

export default function CloudSharePanel() {
  const deviceId = useProfileStore((s) => s.deviceId);
  const [stage, setStage] = useState<Stage>({ kind: "idle" });
  const [file, setFile] = useState<File | null>(null);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [expiryDays, setExpiryDays] = useState(7);
  const [copied, setCopied] = useState(false);
  const [showAdvanced, setShowAdvanced] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  const reset = () => {
    setStage({ kind: "idle" });
    setFile(null);
    setEmail("");
    setPassword("");
    setExpiryDays(7);
    setShowAdvanced(false);
  };

  const handleSend = async () => {
    if (!file) return;
    setStage({ kind: "uploading", loaded: 0, total: file.size });
    try {
      const result = await sendCloud(file, {
        deviceId,
        recipientEmail: email.trim() || undefined,
        password: password.trim() || undefined,
        expiresInDays: expiryDays,
        onProgress: (loaded, total) => setStage({ kind: "uploading", loaded, total }),
      });
      setStage({
        kind: "done",
        shareUrl: result.shareUrl,
        fileName: file.name,
        expiresAt: result.expiresAt,
        password: password.trim() || null,
      });
    } catch (err) {
      setStage({ kind: "error", message: err instanceof Error ? err.message : "unknown" });
    }
  };

  const copy = (value: string) => {
    navigator.clipboard.writeText(value);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  };

  const canShare = typeof navigator !== "undefined" && typeof navigator.share === "function";

  const share = async (url: string, fileName: string) => {
    try {
      await navigator.share({
        title: `AnyDrop — ${fileName}`,
        text: "File shared via AnyDrop",
        url,
      });
    } catch {
      // User canceled the share sheet, or the browser rejected — nothing to do.
    }
  };

  return (
    <div className="paper-panel p-4 sm:p-5">
      {stage.kind === "idle" && (
        <>
          <input
            ref={fileRef}
            type="file"
            className="hidden"
            onChange={(e) => {
              const f = e.target.files?.[0];
              if (f) setFile(f);
            }}
          />

          {file ? (
            <div className="paper-panel-deep rounded-sm px-4 py-3 mb-4">
              <div className="flex items-center justify-between">
                <div className="min-w-0 flex-1 mr-3">
                  <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-ink-muted">
                    File
                  </div>
                  <div className="text-sm text-ink mt-0.5 truncate">{file.name}</div>
                </div>
                <span className="font-mono text-xs text-ink-muted whitespace-nowrap">
                  {formatSize(file.size)}
                </span>
              </div>
              <button
                onClick={() => fileRef.current?.click()}
                className="mt-3 text-xs text-ink-muted hover:text-ink transition-colors"
              >
                Pick another
              </button>
            </div>
          ) : (
            <button
              onClick={() => fileRef.current?.click()}
              className="w-full border border-dashed border-paper-edge hover:border-ink
                         bg-paper rounded-sm px-4 py-6 sm:py-8 mb-4
                         flex flex-col items-center gap-1.5
                         transition-colors duration-fast ease-crisp"
            >
              <span className="font-mono text-[10px] uppercase tracking-[0.2em] text-ink-muted">
                Pick
              </span>
              <span className="font-display text-lg sm:text-xl text-ink">Choose a file</span>
              <span className="text-xs text-ink-muted">Up to 2 GB · 7 days default</span>
            </button>
          )}

          <button
            onClick={() => setShowAdvanced((v) => !v)}
            className="mb-3 font-mono text-[10px] uppercase tracking-[0.22em] text-ink-muted
                       hover:text-ink transition-colors"
          >
            {showAdvanced ? "− Hide options" : "+ Email, password, expiry"}
          </button>

          {showAdvanced && (
            <div className="space-y-3 mb-4 pb-4 border-b border-paper-edge">
              <Field label="Recipient email">
                <input
                  type="email"
                  value={email}
                  onChange={(e) => setEmail(e.target.value)}
                  placeholder="friend@example.com"
                  className={inputCls}
                />
              </Field>

              <Field label="Password">
                <input
                  type="password"
                  value={password}
                  onChange={(e) => setPassword(e.target.value)}
                  placeholder="Leave blank for none"
                  minLength={4}
                  className={inputCls}
                />
              </Field>

              <Field label="Expires in">
                <div className="flex gap-2">
                  {EXPIRY_CHOICES.map((c) => (
                    <button
                      key={c.days}
                      onClick={() => setExpiryDays(c.days)}
                      className={`flex-1 py-2 text-xs rounded-sm border transition-colors duration-fast ease-crisp ${
                        expiryDays === c.days
                          ? "border-ink text-ink bg-paper-deep"
                          : "border-paper-edge text-ink-muted hover:text-ink"
                      }`}
                    >
                      {c.label}
                    </button>
                  ))}
                </div>
              </Field>
            </div>
          )}

          <button
            onClick={handleSend}
            disabled={!file}
            className="w-full py-3 bg-ink text-paper text-sm font-medium rounded-sm
                       hover:bg-signal transition-colors duration-fast ease-crisp
                       disabled:opacity-30 disabled:cursor-not-allowed"
          >
            Encrypt & upload →
          </button>

          <p className="mt-3 text-[11px] text-ink-faint leading-relaxed">
            Sealed in your browser. Only the link holder
            {password && " + password"} can open it.
          </p>
        </>
      )}

      {stage.kind === "uploading" && (
        <>
          <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-ink-muted mb-2">
            Uploading ciphertext
          </div>
          <p className="font-display text-lg sm:text-xl text-ink mb-4">
            Sealing and uploading…
          </p>
          <div className="h-px bg-paper-edge overflow-hidden">
            <div
              className="h-full bg-signal transition-all duration-200"
              style={{
                width: `${stage.total > 0 ? Math.round((stage.loaded / stage.total) * 100) : 0}%`,
              }}
            />
          </div>
          <p className="mt-3 font-mono text-xs text-ink-muted">
            {formatSize(stage.loaded)} / {formatSize(stage.total)}
          </p>
        </>
      )}

      {stage.kind === "done" && (
        <>
          <div className="flex flex-col sm:flex-row sm:items-start gap-4 mb-4">
            <div className="self-center shrink-0 bg-paper p-2 border border-paper-edge rounded-sm">
              <QRCodeSVG
                value={stage.shareUrl}
                size={128}
                bgColor="#F5F0E6"
                fgColor="#2563EB"
              />
            </div>
            <div className="min-w-0 flex-1">
              <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-ok">
                Ready to share
              </div>
              <div className="font-display text-lg text-ink mt-1 tracking-tight truncate">
                {stage.fileName}
              </div>
              <div className="text-xs text-ink-muted mt-1.5">
                Expires {new Date(stage.expiresAt).toLocaleDateString()} · one download
              </div>
            </div>
          </div>

          <div className="flex gap-2">
            {canShare && (
              <button
                onClick={() => share(stage.shareUrl, stage.fileName)}
                className="flex-1 py-2.5 bg-ink text-paper text-sm font-medium rounded-sm
                           hover:bg-signal transition-colors duration-fast ease-crisp"
              >
                Share link →
              </button>
            )}
            <button
              onClick={() => copy(stage.shareUrl)}
              className={`py-2.5 text-sm font-medium rounded-sm transition-colors duration-fast ease-crisp ${
                canShare
                  ? "flex-1 border border-paper-edge hover:border-ink text-ink"
                  : "w-full bg-ink text-paper hover:bg-signal"
              }`}
            >
              {copied ? "Copied ✓" : "Copy link"}
            </button>
          </div>

          <p className="mt-2 font-mono text-[11px] text-ink-faint break-all">
            {stage.shareUrl}
          </p>

          {stage.password && (
            <div className="mt-3 paper-panel-deep rounded-sm px-3 py-2.5">
              <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-ink-muted">
                Password (share separately)
              </div>
              <div className="flex items-center justify-between mt-1">
                <code className="font-mono text-sm text-ink">{stage.password}</code>
                <button
                  onClick={() => copy(stage.password!)}
                  className="text-xs text-ink-muted hover:text-ink transition-colors"
                >
                  Copy
                </button>
              </div>
            </div>
          )}

          <button
            onClick={reset}
            className="mt-4 text-xs text-ink-muted hover:text-ink transition-colors"
          >
            Send another →
          </button>
        </>
      )}

      {stage.kind === "error" && (
        <>
          <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-fail">Failed</div>
          <h3 className="font-display text-lg text-ink mt-1 mb-2">
            Could not complete the transfer
          </h3>
          <p className="font-mono text-xs text-ink-muted">{stage.message}</p>
          <button
            onClick={reset}
            className="mt-4 w-full py-2.5 bg-ink text-paper text-sm font-medium rounded-sm
                       hover:bg-signal transition-colors duration-fast ease-crisp"
          >
            Try again
          </button>
        </>
      )}
    </div>
  );
}

const inputCls =
  "w-full px-3 py-2 bg-paper border border-paper-edge rounded-sm text-ink text-sm " +
  "placeholder:text-ink-faint focus:outline-none focus:border-ink transition-colors " +
  "duration-fast ease-crisp";

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <label className="block">
      <div className="font-mono text-[10px] uppercase tracking-[0.22em] text-ink-muted mb-1.5">
        {label}
      </div>
      {children}
    </label>
  );
}
