import { Lock } from 'lucide-react';

import { useEffect, useState, FormEventHandler } from 'react';

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

import { BillingLink } from '@/Components/billing/BillingLink';
import BrandingPreview from '@/Components/BrandingPreview';
import EditorialPageHeader from '@/Components/layout/EditorialPageHeader';
import { Button } from '@/Components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/Components/ui/card';
import { Checkbox } from '@/Components/ui/checkbox';
import { ConfirmDialog } from '@/Components/ui/confirm-dialog';
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { LoadingButton } from '@/Components/ui/loading-button';
import { useUnsavedChanges } from '@/hooks/useUnsavedChanges';
import DashboardLayout from '@/Layouts/DashboardLayout';
import { trackProductEvent } from '@/lib/analytics';
import { FEATURE_USED, SETTINGS_BRANDING_VIEWED } from '@/lib/event-catalog';
import { cn } from '@/lib/utils';
import type { PageProps } from '@/types';

function getContrastRatio(hex: string): number {
  const r = parseInt(hex.slice(1, 3), 16) / 255;
  const g = parseInt(hex.slice(3, 5), 16) / 255;
  const b = parseInt(hex.slice(5, 7), 16) / 255;
  const toLinear = (c: number) => (c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));
  const lum = 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
  // contrast against white (lum=1)
  return (1 + 0.05) / (lum + 0.05);
}

interface BrandingData {
  company_name: string | null;
  logo_url: string | null;
  primary_color: string;
  secondary_color: string;
  remove_rankwiz_branding: boolean;
  custom_domain: string | null;
}

interface Props {
  branding: BrandingData | null;
  reports_cname_target: string;
  /** WEDGE-GATING-UI: whether the user's plan allows white-labelling PDFs. */
  can_white_label: boolean;
}

export default function Branding({ branding, reports_cname_target, can_white_label }: Props) {
  const { flash } = usePage<PageProps>().props;

  useEffect(() => {
    trackProductEvent(SETTINGS_BRANDING_VIEWED);
    trackProductEvent(FEATURE_USED, { feature: 'settings_branding' });
  }, []);

  const [showDeleteLogo, setShowDeleteLogo] = useState(false);
  const [logoPreview, setLogoPreview] = useState<string | null>(branding?.logo_url ?? null);

  const settingsForm = useForm({
    company_name: branding?.company_name ?? '',
    primary_color: branding?.primary_color ?? '#7C3AED', // white-label seed — user's brand color, cannot reference CSS vars
    secondary_color: branding?.secondary_color ?? '#5B21B6', // white-label seed — user's brand color, cannot reference CSS vars
    remove_rankwiz_branding: branding?.remove_rankwiz_branding ?? false,
    custom_domain: branding?.custom_domain ?? '',
  });
  const { isDirty } = settingsForm;

  const logoForm = useForm({
    logo: null as File | null,
  });

  const deleteLogoForm = useForm({});

  useUnsavedChanges(isDirty);

  const handleSettingsSubmit: FormEventHandler = (e) => {
    e.preventDefault();
    settingsForm.put(route('settings.branding.update'));
  };

  const handleLogoUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    // Client-side validation
    const maxSize = 2 * 1024 * 1024; // 2MB
    const allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/svg+xml'];

    if (!allowedTypes.includes(file.type)) {
      logoForm.setError('logo', 'Logo must be a PNG, JPG, or SVG file.');
      return;
    }

    if (file.size > maxSize) {
      logoForm.setError('logo', 'Logo must be less than 2MB.');
      return;
    }

    logoForm.clearErrors('logo');
    logoForm.setData('logo', file);

    // Show preview
    const reader = new FileReader();
    reader.onload = (event) => {
      setLogoPreview(event.target?.result as string);
    };
    reader.readAsDataURL(file);

    // Auto-upload
    logoForm.post(route('settings.branding.logo.upload'), {
      forceFormData: true,
      onSuccess: () => {
        logoForm.reset();
      },
      onError: () => {
        setLogoPreview(branding?.logo_url ?? null);
      },
    });
  };

  const handleDeleteLogo = () => {
    deleteLogoForm.delete(route('settings.branding.logo.delete'), {
      onSuccess: () => {
        setLogoPreview(null);
        setShowDeleteLogo(false);
      },
    });
  };

  return (
    <DashboardLayout>
      <Head title="Branding" />
      {/* R6UXA-009: reframed from agency 'client deliverables' to solo report personalization */}
      <EditorialPageHeader
        title="Branding"
        subtitle="Add your own logo and colors to personalize your reports and exports"
      />
      <div className="container py-8">
        <div className="max-w-7xl mx-auto">
          {flash.success && (
            <div role="status" className="rounded-md border border-success/20 bg-success/5 px-4 py-3 text-sm text-success-strong mb-6">
              {flash.success}
            </div>
          )}

          <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
            {/* Left Column - Settings Forms */}
            <div className="space-y-6">
              {/* Logo Upload Card */}
              <Card>
                <CardHeader>
                  <CardTitle>Logo</CardTitle>
                  <CardDescription>
                    Upload a logo to appear on your reports and exports.
                  </CardDescription>
                </CardHeader>
                <CardContent>
                  <div className="space-y-4">
                    {logoPreview && (
                      <div className="flex items-center gap-4">
                        <div className="rounded-lg border bg-muted p-4">
                          <img
                            src={logoPreview}
                            alt="Company logo preview"
                            className="max-h-24 max-w-[200px] object-contain"
                          />
                        </div>
                        <Button
                          variant="destructive"
                          size="sm"
                          onClick={() => setShowDeleteLogo(true)}
                          disabled={deleteLogoForm.processing}
                        >
                          Remove Logo
                        </Button>
                        <ConfirmDialog
                          open={showDeleteLogo}
                          onOpenChange={setShowDeleteLogo}
                          title="Remove logo?"
                          description="This will remove your logo from all reports and exports."
                          confirmLabel="Remove Logo"
                          variant="destructive"
                          onConfirm={handleDeleteLogo}
                        />
                      </div>
                    )}

                    <div className="space-y-2">
                      <Label htmlFor="logo-upload">
                        {logoPreview ? 'Update Logo' : 'Upload Logo'}
                      </Label>
                      <Input
                        id="logo-upload"
                        type="file"
                        accept="image/png,image/jpeg,image/jpg,image/svg+xml"
                        onChange={handleLogoUpload}
                        disabled={logoForm.processing}
                      />
                      {logoForm.errors.logo && (
                        <p className="text-sm text-destructive-strong">{logoForm.errors.logo}</p>
                      )}
                      <p className="text-sm text-muted-foreground">
                        PNG, JPG, or SVG. Max file size: 2MB.
                      </p>
                    </div>
                  </div>
                </CardContent>
              </Card>

              {/* Branding Settings Card */}
              <Card>
                <CardHeader>
                  {/* R6UXA-009: removed 'client-facing materials' framing — solo persona */}
                  <CardTitle>Report Styling</CardTitle>
                  <CardDescription>
                    Customize the colors and name that appear on your reports and exports.
                  </CardDescription>
                </CardHeader>
                <CardContent>
                  <form onSubmit={handleSettingsSubmit} className="space-y-6">
                    <div className="space-y-2">
                      {/* R6UXA-009: 'Company Name' → 'Display Name' to avoid agency framing */}
                      <Label htmlFor="company-name">Display Name</Label>
                      <Input
                        id="company-name"
                        type="text"
                        value={settingsForm.data.company_name}
                        onChange={(e) => settingsForm.setData('company_name', e.target.value)}
                        placeholder="Your name or blog name"
                      />
                      {settingsForm.errors.company_name && (
                        <p className="text-sm text-destructive-strong">
                          {settingsForm.errors.company_name}
                        </p>
                      )}
                    </div>

                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                      <div className="space-y-2">
                        <Label htmlFor="primary-color">Primary Color</Label>
                        <div className="flex items-center gap-2">
                          <Input
                            id="primary-color"
                            type="color"
                            value={settingsForm.data.primary_color}
                            onChange={(e) => settingsForm.setData('primary_color', e.target.value)}
                            className="h-10 w-20 cursor-pointer"
                          />
                          <Input
                            id="primary-color-hex"
                            type="text"
                            aria-label="Primary color hex value"
                            value={settingsForm.data.primary_color}
                            onChange={(e) => settingsForm.setData('primary_color', e.target.value)}
                            placeholder="#7C3AED"
                            className="flex-1 font-data"
                          />
                          {/^#[0-9A-Fa-f]{6}$/.test(settingsForm.data.primary_color) &&
                            (() => {
                              const ratio = getContrastRatio(settingsForm.data.primary_color);
                              const passes = ratio >= 4.5;
                              return (
                                <span
                                  className={cn(
                                    'text-xs ml-2 whitespace-nowrap',
                                    passes
                                      ? 'text-success-strong'
                                      : 'text-warning-strong',
                                  )}
                                >
                                  {passes ? '✓' : '⚠'} {ratio.toFixed(1)}:1{' '}
                                  {passes ? 'AA Pass' : 'AA Fail'}
                                </span>
                              );
                            })()}
                        </div>
                        {settingsForm.errors.primary_color && (
                          <p className="text-sm text-destructive-strong">
                            {settingsForm.errors.primary_color}
                          </p>
                        )}
                      </div>

                      <div className="space-y-2">
                        <Label htmlFor="secondary-color">Secondary Color</Label>
                        <div className="flex items-center gap-2">
                          <Input
                            id="secondary-color"
                            type="color"
                            value={settingsForm.data.secondary_color}
                            onChange={(e) =>
                              settingsForm.setData('secondary_color', e.target.value)
                            }
                            className="h-10 w-20 cursor-pointer"
                          />
                          <Input
                            id="secondary-color-hex"
                            type="text"
                            aria-label="Secondary color hex value"
                            value={settingsForm.data.secondary_color}
                            onChange={(e) =>
                              settingsForm.setData('secondary_color', e.target.value)
                            }
                            placeholder="#5B21B6"
                            className="flex-1 font-data"
                          />
                          {/^#[0-9A-Fa-f]{6}$/.test(settingsForm.data.secondary_color) &&
                            (() => {
                              const ratio = getContrastRatio(settingsForm.data.secondary_color);
                              const passes = ratio >= 4.5;
                              return (
                                <span
                                  className={cn(
                                    'text-xs ml-2 whitespace-nowrap',
                                    passes
                                      ? 'text-success-strong'
                                      : 'text-warning-strong',
                                  )}
                                >
                                  {passes ? '✓' : '⚠'} {ratio.toFixed(1)}:1{' '}
                                  {passes ? 'AA Pass' : 'AA Fail'}
                                </span>
                              );
                            })()}
                        </div>
                        {settingsForm.errors.secondary_color && (
                          <p className="text-sm text-destructive-strong">
                            {settingsForm.errors.secondary_color}
                          </p>
                        )}
                      </div>
                    </div>

                    {/* WEDGE-GATING-UI: white-label toggle — visible but disabled for free users.
                        Paid users get it enabled (default off = opt-in, not opt-out).
                        Server-side: UpdateBrandingSettingsRequest enforces the cap (defense-in-depth). */}
                    <div className="flex items-start space-x-2">
                      <Checkbox
                        id="remove-branding"
                        checked={settingsForm.data.remove_rankwiz_branding}
                        disabled={!can_white_label}
                        aria-disabled={!can_white_label}
                        aria-describedby={!can_white_label ? 'remove-branding-upgrade' : undefined}
                        onCheckedChange={(checked) => {
                          if (can_white_label) {
                            settingsForm.setData('remove_rankwiz_branding', checked as boolean);
                          }
                        }}
                        className={!can_white_label ? 'opacity-50 cursor-not-allowed' : undefined}
                      />
                      <div className="flex flex-col gap-0.5">
                        <Label
                          htmlFor="remove-branding"
                          className={cn(
                            'text-sm font-normal',
                            can_white_label ? 'cursor-pointer' : 'cursor-not-allowed opacity-60',
                          )}
                        >
                          Remove RankWizAI branding from reports
                        </Label>
                        {!can_white_label && (
                          <p
                            id="remove-branding-upgrade"
                            className="text-xs text-muted-foreground flex items-center gap-1"
                          >
                            <Lock className="size-3 shrink-0" aria-hidden="true" />
                            <span>
                              Remove on a paid plan —{' '}
                              <BillingLink
                                params={{ highlight: 'pro' }}
                                className="underline underline-offset-2 hover:text-foreground"
                              >
                                share recovery evidence under your own name
                              </BillingLink>
                            </span>
                          </p>
                        )}
                      </div>
                    </div>

                    <div className="space-y-2">
                      <Label htmlFor="custom-domain">
                        Custom Domain <span className="text-muted-foreground">(Optional)</span>
                      </Label>
                      <Input
                        id="custom-domain"
                        type="text"
                        value={settingsForm.data.custom_domain}
                        onChange={(e) => settingsForm.setData('custom_domain', e.target.value)}
                        placeholder="reports.yourcompany.com"
                      />
                      {settingsForm.errors.custom_domain && (
                        <p className="text-sm text-destructive-strong">
                          {settingsForm.errors.custom_domain}
                        </p>
                      )}
                      <p className="text-sm text-muted-foreground">
                        Point your domain's CNAME record to {reports_cname_target}
                      </p>
                    </div>

                    <LoadingButton
                      type="submit"
                      loading={settingsForm.processing}
                      loadingText="Saving..."
                    >
                      Save Branding Settings
                    </LoadingButton>
                  </form>
                </CardContent>
              </Card>
            </div>

            {/* Right Column - Preview */}
            <div className="lg:sticky lg:top-6 lg:self-start">
              <BrandingPreview
                companyName={settingsForm.data.company_name}
                logoUrl={logoPreview}
                primaryColor={settingsForm.data.primary_color}
                secondaryColor={settingsForm.data.secondary_color}
                removeRankwizBranding={settingsForm.data.remove_rankwiz_branding}
              />
            </div>
          </div>
        </div>
      </div>
    </DashboardLayout>
  );
}
