'use client';

import { useState } from 'react';
import { CheckCircle2, HelpCircle, Loader2, XCircle } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet';
import {
  SettingsFormCard,
  type SettingFieldDef,
} from '@/components/admin/shared/settings-form-card';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

interface TestResult {
  ok: boolean;
  host?: string;
  checks?: Array<{ path: string; status?: number; ok: boolean; error?: string }>;
  error?: string;
  at: Date;
}

const EMBED_FIELDS: SettingFieldDef[] = [
  {
    key: 'embedded_signing_host',
    label: 'Embedded signing host',
    description:
      "Origin of the public site that hosts the embedded Documenso signing pages. Outbound emails wrap raw Documenso signing URLs into {host}/sign/<type>/<token> so clients sign on your branded page rather than Documenso's domain. Leave blank to fall back to the app URL. Marketing-website pattern: https://portnimara.com",
    type: 'string',
    placeholder: 'https://portnimara.com',
    defaultValue: '',
  },
];

/**
 * Admin card for the embedded-signing host setting. Provides:
 *   - The setting field itself (via SettingsFormCard)
 *   - A Test connection button that probes the host's `/` and
 *     `/sign/success` paths to verify the marketing-site cutover is
 *     ready BEFORE signers get sent there from outbound emails.
 *   - A Help button that opens a Sheet with the setup instructions —
 *     what routes the marketing site needs, what URL parameters to
 *     handle, and the Documenso webhook config that pairs with it.
 */
export function EmbeddedSigningCard() {
  const [testing, setTesting] = useState(false);
  const [result, setResult] = useState<TestResult | null>(null);
  const [helpOpen, setHelpOpen] = useState(false);

  const handleTest = async () => {
    setTesting(true);
    setResult(null);
    try {
      const res = (await apiFetch('/api/v1/admin/embedded-signing/test', {
        method: 'POST',
        body: {},
      })) as {
        data: {
          ok: boolean;
          host?: string;
          error?: string;
          checks?: Array<{ path: string; status?: number; ok: boolean; error?: string }>;
        };
      };
      setResult({ ...res.data, at: new Date() });
      if (res.data.ok) toast.success('Embedded signing host reachable.');
      else toast.error('Embedded signing host probe failed — see card.');
    } catch (err) {
      toastError(err);
      setResult({
        ok: false,
        error: err instanceof Error ? err.message : String(err),
        at: new Date(),
      });
    } finally {
      setTesting(false);
    }
  };

  return (
    <>
      <Card>
        <CardHeader>
          <div className="flex items-start justify-between gap-2">
            <div>
              <CardTitle>Embedded signing</CardTitle>
              <CardDescription>
                Where the public-facing branded signing pages live. The CRM rewrites Documenso
                signing URLs to point here when sending invitation and reminder emails.
              </CardDescription>
            </div>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              onClick={() => setHelpOpen(true)}
              className="gap-1.5 [&_svg]:size-3.5"
            >
              <HelpCircle />
              Setup help
            </Button>
          </div>
        </CardHeader>
        <CardContent className="space-y-4">
          {/* Renders inside our outer Card with its own micro-header.
              Title kept terse (empty string would look broken) so the
              user still has a visual anchor for the field. */}
          <SettingsFormCard title="Host URL" description="" fields={EMBED_FIELDS} />
          <div className="flex flex-wrap items-center gap-2">
            <Button
              variant="outline"
              onClick={handleTest}
              disabled={testing}
              className="gap-1.5 [&_svg]:size-3.5"
            >
              {testing ? <Loader2 className="animate-spin" aria-hidden /> : null}
              Test connection
            </Button>
            <p className="text-xs text-muted-foreground">
              Probes <code>/</code> and <code>/sign/success</code> on the configured host.
            </p>
          </div>

          {result ? (
            <div
              className={`rounded-md border p-3 text-sm ${
                result.ok
                  ? 'border-emerald-200 bg-emerald-50 text-emerald-900'
                  : 'border-rose-200 bg-rose-50 text-rose-900'
              }`}
            >
              <div className="flex items-start gap-2">
                {result.ok ? (
                  <CheckCircle2 className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
                ) : (
                  <XCircle className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
                )}
                <div className="flex-1">
                  <p className="font-medium">{result.ok ? 'Connection ok' : 'Connection failed'}</p>
                  {result.host ? (
                    <p className="text-xs">
                      Host: <code>{result.host}</code>
                    </p>
                  ) : null}
                  {result.error ? <p className="text-xs">{result.error}</p> : null}
                  {result.checks ? (
                    <ul className="mt-1 space-y-0.5 text-xs">
                      {result.checks.map((c) => (
                        <li key={c.path}>
                          <code>{c.path}</code> →{' '}
                          {c.ok ? (
                            <span className="text-emerald-800">{c.status ?? 'ok'}</span>
                          ) : (
                            <span className="text-rose-800">
                              {c.status ? `${c.status} fail` : (c.error ?? 'fail')}
                            </span>
                          )}
                        </li>
                      ))}
                    </ul>
                  ) : null}
                  <p className="mt-1 text-[11px] opacity-70">{result.at.toLocaleTimeString()}</p>
                </div>
              </div>
            </div>
          ) : null}
        </CardContent>
      </Card>

      <Sheet open={helpOpen} onOpenChange={setHelpOpen}>
        <SheetContent side="right" className="overflow-y-auto sm:max-w-xl">
          <SheetHeader>
            <SheetTitle>Set up embedded signing</SheetTitle>
            <SheetDescription>
              How the marketing site has to be wired up so the branded signing flow works.
            </SheetDescription>
          </SheetHeader>

          <div className="space-y-4 pt-4 text-sm leading-6">
            <section>
              <h3 className="mb-1 font-semibold">1. Choose the host</h3>
              <p className="text-muted-foreground">
                Pick a public host (e.g. <code>https://portnimara.com</code>) and enter it in the
                Embedded signing host field above. The CRM rewrites raw Documenso signing URLs into{' '}
                <code>{'{host}/sign/<role>/<token>'}</code> for every outbound invitation + reminder
                email.
              </p>
            </section>

            <section>
              <h3 className="mb-1 font-semibold">2. Implement the signing route</h3>
              <p className="text-muted-foreground">
                The marketing site needs to handle <code>/sign/[role]/[token]</code> by forwarding
                to the underlying Documenso signing URL (or embedding it in an iframe). Role is one
                of <code>client</code> / <code>developer</code> / <code>approver</code> — useful for
                tracking which slot the signer is in.
              </p>
              <p className="mt-1 text-muted-foreground">Minimum Next.js example:</p>
              <pre className="mt-1 overflow-x-auto rounded bg-muted p-2 font-mono text-[11px]">
                {`// app/sign/[role]/[token]/page.tsx
export default function SignPage({ params }) {
  const documenseUrl = \`\${env.DOCUMENSO_URL}/sign/\${params.token}\`;
  return <iframe src={documenseUrl} className="w-full h-screen" />;
}`}
              </pre>
            </section>

            <section>
              <h3 className="mb-1 font-semibold">3. Implement the success route</h3>
              <p className="text-muted-foreground">
                After signing, Documenso redirects to the URL configured in{' '}
                <strong>Post-sign redirect URL</strong>. Default points at{' '}
                <code>{'{host}/sign/success'}</code>. Render a confirmation page there (the
                signer&apos;s already done; this is just the friendly &ldquo;Thanks!&rdquo; UX).
              </p>
            </section>

            <section>
              <h3 className="mb-1 font-semibold">4. Test the connection</h3>
              <p className="text-muted-foreground">
                Use the Test connection button to verify <code>/</code> and{' '}
                <code>/sign/success</code> return 2xx. If either fails, the marketing site
                isn&apos;t ready — fix the route before flipping live or signers will land on a 404
                page from outbound emails.
              </p>
            </section>

            <section>
              <h3 className="mb-1 font-semibold">5. Pair the Documenso webhook</h3>
              <p className="text-muted-foreground">
                Make sure the Documenso webhook points at{' '}
                <code>{'{appUrl}/api/webhooks/documenso'}</code> with the matching webhook secret
                stored under Documenso → API → Webhook secret. Without this the EOI status never
                updates after signing.
              </p>
            </section>

            <section>
              <h3 className="mb-1 font-semibold">6. Cutover</h3>
              <p className="text-muted-foreground">
                Flip the Embedded signing host field to your live URL and save. Existing in-flight
                EOIs keep their pre-cutover signing URLs (the rewrite happens at email-dispatch
                time, not at envelope creation), so old signers can still complete on the old host
                until they sign or the EOI is cancelled.
              </p>
            </section>
          </div>
        </SheetContent>
      </Sheet>
    </>
  );
}
