import { AlertTriangle, ArrowRight, CheckCircle2, ChevronDown, ExternalLink, Eye, EyeOff, Lock, Sparkles, XCircle } from 'lucide-react';

import { useEffect, useState } from 'react';

import { Head, Link, useForm, usePage } from '@inertiajs/react';

import InputError from '@/Components/InputError';
import EditorialPageHeader from '@/Components/layout/EditorialPageHeader';
import { SerpQuotaMeter } from '@/Components/serp/SerpQuotaMeter';
import { Alert, AlertDescription, AlertTitle } from '@/Components/ui/alert';
import { Badge } from '@/Components/ui/badge';
import { Button } from '@/Components/ui/button';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import { Input } from '@/Components/ui/input';
import { LoadingButton } from '@/Components/ui/loading-button';
import { useFlashToasts } from '@/hooks/useFlashToasts';
import { useUnsavedChanges } from '@/hooks/useUnsavedChanges';
import DashboardLayout from '@/Layouts/DashboardLayout';
import { trackProductEvent } from '@/lib/analytics';
import { FEATURE_USED, SERP_SETTINGS_VIEWED } from '@/lib/event-catalog';
import { formatDateTime } from '@/lib/format';
import type { PageProps } from '@/types';

import { validationInfoMap, STATUS_ALIASES } from './serpValidationInfo';

interface KeyValidation {
  status: string;
  message: string | null;
  at: string | null;
  consecutiveFailures: number;
}

interface Props {
  has_key: boolean;
  masked_login: string | null;
  provider: string | null;
  is_validated: boolean;
  validated_at: string | null;
  key_validation: KeyValidation | null;
}

const validationBadgeVariant: Record<string, 'success' | 'destructive' | 'default'> = {
  valid: 'success',
  invalid_auth: 'destructive',
  quota_exceeded: 'destructive',
  rate_limited: 'default',
  network_error: 'default',
  provider_error: 'default',
};

/**
 * R3UXA-008: Prominent on-load validation banner for SerpKey,
 * mirroring AiKey's MED-006 pattern.
 */
type BannerSeverity = 'destructive' | 'warning';

const serpValidationBannerSeverity: Record<string, BannerSeverity> = {
  invalid_auth: 'destructive',
  quota_exceeded: 'destructive',
  rate_limited: 'warning',
  network_error: 'warning',
  provider_error: 'warning',
};

const serpValidationBannerTitle: Record<string, string> = {
  invalid_auth: 'Your DataForSEO credentials were rejected',
  quota_exceeded: 'DataForSEO account has run out of credits',
  rate_limited: 'DataForSEO is throttling your account',
  network_error: 'Could not reach DataForSEO',
  provider_error: 'DataForSEO returned an unexpected error',
};

export default function SerpKeySettings({
  has_key,
  masked_login,
  is_validated,
  validated_at,
  key_validation,
}: Props) {
  useEffect(() => {
    trackProductEvent(SERP_SETTINGS_VIEWED);
    trackProductEvent(FEATURE_USED, { feature: 'settings_serp_key' });
  }, []);

  const { features, plan, sites, active_jobs } = usePage<PageProps>().props;
  const isFreeTier = features.billing && plan === 'free';
  const firstSite = sites.length > 0 ? sites[0] : null;
  const [showDelete, setShowDelete] = useState(false);
  const [educationExpanded, setEducationExpanded] = useState(!has_key);
  // F4UXA-002: reveal toggle for DataForSEO password input — default hidden
  const [showPassword, setShowPassword] = useState(false);
  const { data, setData, post, processing, errors, isDirty, reset } = useForm({
    provider: 'dataforseo',
    login: '',
    password: '',
  });
  const validateForm = useForm({});
  const deleteForm = useForm({});

  useUnsavedChanges(isDirty);
  useFlashToasts();

  const submitKey = (e: React.FormEvent) => {
    e.preventDefault();
    post(route('settings.serp.store'), {
      // R3FE-012: clear secret fields after a successful save.
      onSuccess: () => reset('login', 'password'),
    });
  };

  const handleValidate = () => {
    validateForm.post(route('settings.serp.validate'));
  };

  const rawValidationState = key_validation?.status ?? (is_validated ? 'valid' : null);
  const validationState = rawValidationState
    ? (STATUS_ALIASES[rawValidationState] ?? rawValidationState)
    : null;

  // SERP analysis is "ready to use" only when the key is connected AND validated.
  // An unvalidated/invalid key keeps the existing validate/fix guidance instead.
  const isReady = has_key && validationState === 'valid';

  // R3UXA-008: prominent on-load validation banner (mirrors AiKey MED-006 pattern).
  const bannerSeverity =
    validationState && validationState in serpValidationBannerSeverity
      ? serpValidationBannerSeverity[validationState]
      : null;
  const bannerTitle = validationState ? serpValidationBannerTitle[validationState] : null;
  const bannerMessage =
    key_validation?.message ?? (validationState ? validationInfoMap[validationState]?.message : null);
  const showValidationBanner = has_key && bannerSeverity !== null && bannerTitle && bannerMessage;

  return (
    <>
      <Head title="SERP API Settings" />

      <div className="container py-8">
        <EditorialPageHeader
          title="SERP API Settings"
          subtitle="Add your DataForSEO credentials to enable SERP competitor scoring in the Content Editor."
        />

        {/* F-SERP_AUTOFETCH launch: advertise the platform-paid competitor SERP
            differentiator + its honest per-user monthly cap. Renders the "X of Y
            left" meter, or the upgrade-aware nudge once the user is at cap. */}
        <SerpQuotaMeter className="max-w-2xl mt-6" />

        {/* R3UXA-008: Prominent validation banner — surfaces failed SERP key state
            on page load so users notice immediately that SERP scoring is broken. */}
        {showValidationBanner && bannerSeverity && (
          <Alert
            variant={bannerSeverity}
            role="alert"
            data-testid="serp-key-validation-banner"
            className="max-w-2xl mt-6"
          >
            {bannerSeverity === 'destructive' ? (
              <XCircle className="size-4" />
            ) : (
              <AlertTriangle className="size-4" />
            )}
            <AlertTitle>{bannerTitle}</AlertTitle>
            <AlertDescription>{bannerMessage}</AlertDescription>
          </Alert>
        )}

        {/* "Ready to use" next-step panel — appears once the key is connected and
            validated, since SERP scoring lives inside the Content Editor and is
            otherwise hard to discover from this settings page. */}
        {isReady && (
          <div className="max-w-2xl mt-6 rounded-lg border border-success-border bg-success-soft p-6">
            <div className="flex items-start gap-3">
              <CheckCircle2
                className="size-5 text-success-strong shrink-0 mt-0.5"
                aria-hidden="true"
              />
              <div className="space-y-3">
                <div>
                  <h3 className="text-base font-semibold text-success-strong">
                    You&rsquo;re ready for SERP analysis
                  </h3>
                  <p className="text-sm text-muted-foreground mt-1">
                    SERP scoring runs inside the Content Editor. Open any draft, switch to the{' '}
                    <span className="font-medium text-foreground">Score</span> tab, and enter a
                    target keyword &mdash; RankWizAI analyzes the top-ranking competitors and scores
                    your content against the terms they cover.
                  </p>
                </div>
                {firstSite ? (
                  <div className="space-y-2">
                    <Button size="sm" variant="default" asChild>
                      <Link href={route('pipeline.index', firstSite.id)}>
                        Go to your drafts
                        <ArrowRight className="ml-2 size-4" aria-hidden="true" />
                      </Link>
                    </Button>
                    <p className="text-xs text-muted-foreground">
                      No draft yet? Generate one from your recommendations first &mdash; then open
                      it in the Content Editor to score it.
                    </p>
                  </div>
                ) : (
                  <p className="text-sm text-muted-foreground">
                    Add a site and generate a draft to start scoring your content.
                  </p>
                )}
              </div>
            </div>
          </div>
        )}

        {isFreeTier && (
          <Alert className="max-w-2xl mt-6 border-primary/30 bg-primary/10">
            <Sparkles className="size-4 text-primary" />
            <AlertDescription>
              <p className="font-medium text-primary">
                SERP analysis is available on all plans. Upgrade to Pro for higher usage limits and
                priority processing.
              </p>
              <Link href={route('pricing')}>
                <Button size="sm" variant="default" className="mt-2">
                  View Pricing
                </Button>
              </Link>
            </AlertDescription>
          </Alert>
        )}

        {/* Educational Section */}
        <div className="max-w-2xl mt-6 rounded-lg border bg-card p-6">
          <button
            aria-expanded={educationExpanded}
            onClick={() => setEducationExpanded(!educationExpanded)}
            className="w-full flex items-center justify-between hover:opacity-80 transition-opacity rounded-lg outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
          >
            <h3 className="text-lg font-medium">How Content Scoring Works</h3>
            <ChevronDown
              className={`size-5 text-muted-foreground transition-transform duration-200 ${
                educationExpanded ? 'rotate-180' : ''
              }`}
            />
          </button>

          {educationExpanded && (
            <div className="mt-4 space-y-4">
              <div>
                <h4 className="font-medium text-foreground mb-2">What is Content Scoring?</h4>
                <p className="text-sm text-muted-foreground">
                  RankWizAI analyzes your top-ranking competitors for a target keyword, extracts the
                  semantic terms they use, and scores your content against their coverage. This
                  helps you close content gaps and match search intent.
                </p>
              </div>

              <div>
                <h4 className="font-medium text-foreground mb-2">
                  How to Get DataForSEO Credentials
                </h4>
                <ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
                  <li>
                    Go to{' '}
                    <a
                      href="https://app.dataforseo.com/register"
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-primary hover:underline inline-flex items-center gap-1"
                    >
                      app.dataforseo.com/register
                      <ExternalLink className="size-3" />
                    </a>
                  </li>
                  <li>Create an account and add a payment method</li>
                  <li>Your login (email) and password are your API credentials</li>
                  <li>Enter them below</li>
                </ol>
              </div>

              <div>
                <h4 className="font-medium text-foreground mb-2">Cost Transparency</h4>
                <p className="text-sm text-muted-foreground">
                  Each SERP analysis costs approximately <strong>$0.02 - $0.10</strong> depending on
                  result depth. You pay DataForSEO directly for usage.
                </p>
              </div>

              <Alert className="bg-background border-primary/20">
                <Lock className="size-4 text-primary" />
                <AlertDescription className="text-sm">
                  Your credentials are encrypted at rest and never logged or shared.
                </AlertDescription>
              </Alert>
            </div>
          )}
        </div>

        {/* Credentials Input Section */}
        <div className="max-w-md mt-6 rounded-lg border bg-card p-6">
          <h3 className="text-lg font-medium">DataForSEO Credentials</h3>

          {has_key ? (
            <div className="mt-4">
              <div className="flex items-center gap-2">
                <span className="text-sm">Status:</span>
                {validationState ? (
                  <Badge variant={validationBadgeVariant[validationState] ?? 'default'}>
                    {validationState}
                  </Badge>
                ) : (
                  <Badge variant="secondary">unvalidated</Badge>
                )}
              </div>
              {validationState && validationInfoMap[validationState] && (
                <div className="mt-2 space-y-1">
                  <p className="text-sm text-muted-foreground">
                    {validationInfoMap[validationState].message}
                  </p>
                  {validationInfoMap[validationState].actionUrl && (
                    <a
                      href={validationInfoMap[validationState].actionUrl}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="text-sm text-primary hover:underline inline-flex items-center gap-1"
                    >
                      {validationInfoMap[validationState].action}
                      <ExternalLink className="size-3" />
                    </a>
                  )}
                </div>
              )}
              {key_validation?.message && (
                <p className="text-sm text-muted-foreground mt-1">{key_validation.message}</p>
              )}
              {masked_login && (
                <p className="text-sm font-data text-muted-foreground mt-1">Login: {masked_login}</p>
              )}
              {validated_at && (
                <p className="text-sm text-muted-foreground">
                  Last validated: {formatDateTime(validated_at)}
                </p>
              )}
              {key_validation?.at && (
                <p className="text-sm text-muted-foreground">
                  Last check: {formatDateTime(key_validation.at)}
                </p>
              )}
              <div className="flex gap-2 mt-4">
                <LoadingButton loading={validateForm.processing} onClick={handleValidate} size="sm">
                  Test Credentials
                </LoadingButton>
                <Button
                  variant="destructive"
                  size="sm"
                  onClick={() => setShowDelete(true)}
                  disabled={deleteForm.processing}
                >
                  Remove
                </Button>
                <ConfirmDialog
                  open={showDelete}
                  onOpenChange={setShowDelete}
                  title="Remove SERP API credentials?"
                  description={(() => {
                    // F4UXA-012: surface in-flight SERP analysis job count
                    const activeAnalysisJobs = (active_jobs ?? []).filter(
                      (j) => j.type === 'analysis',
                    );
                    const base =
                      'This will disable content scoring features. You can add new credentials later.';
                    if (activeAnalysisJobs.length > 0) {
                      return `${base} ${activeAnalysisJobs.length} analysis job${activeAnalysisJobs.length > 1 ? 's are' : ' is'} currently running and may be affected.`;
                    }
                    return base;
                  })()}
                  confirmLabel="Remove Credentials"
                  variant="destructive"
                  onConfirm={() => deleteForm.delete(route('settings.serp.destroy'))}
                />
              </div>
              <hr className="my-4" />
              <p className="text-sm text-muted-foreground mb-3">Update credentials:</p>
            </div>
          ) : (
            <p className="text-sm text-muted-foreground mt-2 mb-4">
              Enter your DataForSEO credentials to enable competitive content scoring.
            </p>
          )}

          <form onSubmit={submitKey} className="space-y-3">
            <div>
              <label htmlFor="serp-login" className="text-sm font-medium">
                Login (Email)
              </label>
              <Input
                id="serp-login"
                type="email"
                value={data.login}
                onChange={(e) => setData('login', e.target.value)}
                placeholder="your@email.com"
                className="mt-1"
                aria-invalid={!!errors.login}
                aria-describedby={errors.login ? 'login-error' : undefined}
              />
              <InputError id="login-error" message={errors.login} className="mt-1" />
            </div>
            <div>
              <label htmlFor="serp-password" className="text-sm font-medium">
                DataForSEO API Password
              </label>
              <p className="text-xs text-muted-foreground mt-0.5">
                Your DataForSEO account login email and password — not a new RankWizAI password.
              </p>
              {/* F4UXA-002: reveal toggle for DataForSEO password — mirrors AiKey pattern */}
              <div className="relative flex items-center mt-1">
                <Input
                  id="serp-password"
                  type={showPassword ? 'text' : 'password'}
                  value={data.password}
                  onChange={(e) => setData('password', e.target.value)}
                  placeholder="Your DataForSEO account password"
                  className="pr-10"
                  autoComplete="off"
                  aria-invalid={!!errors.password}
                  aria-describedby={
                    errors.password ? 'password-error serp-password-hint' : 'serp-password-hint'
                  }
                />
                <button
                  type="button"
                  onClick={() => setShowPassword(!showPassword)}
                  className="absolute right-3 text-muted-foreground hover:text-foreground transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm"
                  aria-label={showPassword ? 'Hide password' : 'Show password'}
                  aria-pressed={showPassword}
                >
                  {showPassword ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
                </button>
              </div>
              <p id="serp-password-hint" className="sr-only">
                This is the password for your DataForSEO account, not a RankWizAI password.
              </p>
              <InputError id="password-error" message={errors.password} className="mt-1" />
            </div>
            <LoadingButton loading={processing}>
              {has_key ? 'Update Credentials' : 'Save Credentials'}
            </LoadingButton>
          </form>
        </div>
      </div>
    </>
  );
}

SerpKeySettings.layout = (page: React.ReactNode) => <DashboardLayout>{page}</DashboardLayout>;
