import { useEffect, useRef, useState, FormEvent } from 'react';
import { Head, Link, useForm } from '@inertiajs/react';
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 { Checkbox } from '@/components/ui/checkbox';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { toast } from 'sonner';
import { Loader2, Eye, EyeOff, Building2, Check, X } from 'lucide-react';
import Navbar from '@/components/Navbar';
import Footer from '@/components/Footer';

type AccountType = 'company' | 'individual';
type CheckStatus = 'idle' | 'checking' | 'available' | 'taken' | 'invalid';

// Mirror the backend regex: optional +, 7–20 chars made of digits/space/dash/dot/paren,
// must contain 7–15 actual digits.
const PHONE_REGEX = /^\+?[0-9\s\-.()]{7,20}$/;
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

const countDigits = (s: string) => (s.match(/\d/g) || []).length;

const companyTypeLabel = (type: string) => {
  switch (type) {
    case 'customer_company': return 'We purchase training courses for our staff';
    case 'training_company': return 'We deliver and sell training courses';
    case 'hybrid': return 'We both purchase and deliver training';
    default: return '';
  }
};

const isValidPhone = (v: string) => {
  if (!v) return false;
  if (!PHONE_REGEX.test(v)) return false;
  const digits = countDigits(v);
  return digits >= 7 && digits <= 15;
};

const isValidEmail = (v: string) => EMAIL_REGEX.test(v);

export default function Register() {
  const [accountType, setAccountType] = useState<AccountType>('individual');
  const [success, setSuccess] = useState<{ email: string; type: AccountType } | null>(null);
  const [showPassword, setShowPassword] = useState(false);
  const [showConfirmPassword, setShowConfirmPassword] = useState(false);

  const [emailCheck, setEmailCheck] = useState<CheckStatus>('idle');
  const [companyCheck, setCompanyCheck] = useState<CheckStatus>('idle');
  const [accountsEmailCheck, setAccountsEmailCheck] = useState<CheckStatus>('idle');

  // Honeypot + render-time anti-bot. The "website" input is hidden from real users via CSS
  // but visible to dumb form-fillers. The timestamp lets the backend reject sub-2s submits.
  const formRenderedAt = useRef<number>(Date.now());

  const { data, setData, post, processing, errors, reset, transform } = useForm({
    account_type: 'individual',
    // Company-only fields
    company_type: 'customer_company',
    company_name: '',
    registration_number: '',
    vat_number: '',
    company_address: '',
    contact_phone: '',
    accounts_contact_name: '',
    accounts_contact_email: '',
    // Shared
    full_name: '',
    phone: '',
    email: '',
    password: '',
    password_confirmation: '',
    agreed_terms: false,
    // Anti-bot
    website: '',
    form_rendered_at: formRenderedAt.current,
  });

  useEffect(() => {
    setData('account_type', accountType);
  }, [accountType]);

  // Debounced availability check. Runs whenever the relevant field changes and is
  // shaped correctly. Reuses the route alias so deployment moves don't break it.
  useEffect(() => {
    if (!data.email || !isValidEmail(data.email)) {
      setEmailCheck(data.email ? 'invalid' : 'idle');
      return;
    }
    setEmailCheck('checking');
    const t = window.setTimeout(() => {
      checkAvailability('email', data.email)
        .then((available) => setEmailCheck(available ? 'available' : 'taken'))
        .catch(() => setEmailCheck('idle'));
    }, 500);
    return () => window.clearTimeout(t);
  }, [data.email]);

  useEffect(() => {
    if (accountType !== 'company') return;
    if (!data.accounts_contact_email) {
      setAccountsEmailCheck('idle');
      return;
    }
    setAccountsEmailCheck(isValidEmail(data.accounts_contact_email) ? 'idle' : 'invalid');
  }, [data.accounts_contact_email, accountType]);

  useEffect(() => {
    if (accountType !== 'company') return;
    const name = data.company_name.trim();
    if (!name || name.length < 2) {
      setCompanyCheck('idle');
      return;
    }
    setCompanyCheck('checking');
    const t = window.setTimeout(() => {
      checkAvailability('company_name', name)
        .then((available) => setCompanyCheck(available ? 'available' : 'taken'))
        .catch(() => setCompanyCheck('idle'));
    }, 500);
    return () => window.clearTimeout(t);
  }, [data.company_name, accountType]);

  const submit = (e: FormEvent) => {
    e.preventDefault();

    if (!isValidEmail(data.email)) {
      toast.error('Please enter a valid email address');
      return;
    }
    if (emailCheck === 'taken') {
      toast.error('This email is already registered');
      return;
    }
    if (data.password !== data.password_confirmation) {
      toast.error('Passwords do not match');
      return;
    }
    if (data.password.length < 8) {
      toast.error('Password must be at least 8 characters long');
      return;
    }
    if (!data.agreed_terms) {
      toast.error('You must agree to the Terms of Service and Privacy Policy');
      return;
    }
    if (accountType === 'individual' && data.phone && !isValidPhone(data.phone)) {
      toast.error('Please enter a valid phone number, or leave it blank');
      return;
    }

    if (accountType === 'company') {
      if (companyCheck === 'taken') {
        toast.error('A company with this name is already registered');
        return;
      }
      if (!isValidPhone(data.contact_phone)) {
        toast.error('Please enter a valid phone number');
        return;
      }
      if (!isValidEmail(data.accounts_contact_email)) {
        toast.error('Please enter a valid accounts contact email');
        return;
      }
    }

    transform((d) => {
      const submission: Record<string, unknown> = {
        account_type: accountType,
        full_name: d.full_name,
        email: d.email,
        password: d.password,
        password_confirmation: d.password_confirmation,
        agreed_terms: d.agreed_terms,
        website: d.website,
        form_rendered_at: d.form_rendered_at,
      };
      if (accountType === 'company') {
        Object.assign(submission, {
          company_type: d.company_type,
          company_name: d.company_name,
          registration_number: d.registration_number,
          vat_number: d.vat_number,
          company_address: d.company_address,
          contact_phone: d.contact_phone,
          accounts_contact_name: d.accounts_contact_name,
          accounts_contact_email: d.accounts_contact_email,
        });
      }
      // Optional personal phone — only sent when provided so a blank field
      // doesn't trip the format validation server-side.
      if (d.phone.trim()) submission.phone = d.phone.trim();
      return submission;
    });

    post(route('register'), {
      preserveScroll: true,
      onSuccess: () => {
        setSuccess({ email: data.email, type: accountType });
        reset(
          'company_name', 'registration_number', 'vat_number', 'company_address',
          'contact_phone', 'accounts_contact_name', 'accounts_contact_email',
          'full_name', 'phone', 'email', 'password', 'password_confirmation',
        );
      },
      onError: (errs) => {
        const first = Object.values(errs)[0];
        if (first) toast.error(String(first));
      },
    });
  };

  if (success) {
    return (
      <>
        <Head title={success.type === 'individual' ? 'Account Created' : 'Application Submitted'} />
        <div className="min-h-screen bg-background">
          <Navbar />
          <div className="container mx-auto px-4 py-24 flex justify-center">
            <div className="bg-card border border-border rounded-xl p-8 max-w-md w-full text-center space-y-4">
              <Building2 className="w-16 h-16 text-primary mx-auto" />
              <h2 className="text-2xl font-bold text-foreground">
                {success.type === 'individual' ? 'Account Created!' : 'Application Submitted!'}
              </h2>
              <p className="text-muted-foreground">
                {success.type === 'individual'
                  ? <>Your account has been created. You can now start booking courses.</>
                  : <>Your company account request has been submitted to our accounts department for review. Once it's approved you'll receive a confirmation email at <strong>{success.email}</strong>, and you'll then be able to sign in.</>}
              </p>
              <Link href="/">
                <Button className="mt-4">Back to Home</Button>
              </Link>
            </div>
          </div>
          <Footer />
        </div>
      </>
    );
  }

  const phoneInvalid = data.contact_phone.length > 0 && !isValidPhone(data.contact_phone);
  const personalPhoneInvalid = data.phone.length > 0 && !isValidPhone(data.phone);

  return (
    <>
      <Head title="Create an Account" />
      <div className="min-h-screen bg-background">
        <Navbar />
        <div className="container mx-auto px-4 py-24 flex justify-center">
          <div className="bg-card border border-border rounded-xl p-8 max-w-lg w-full">
            <h1 className="text-2xl font-bold text-foreground mb-2 text-center">Create an Account</h1>
            <p className="text-sm text-muted-foreground text-center mb-6">
              Register as a company or an individual to get started.
            </p>

            <div className="flex rounded-lg border border-border overflow-hidden mb-6">
              <button
                type="button"
                onClick={() => setAccountType('individual')}
                className={`flex-1 py-2.5 text-sm font-medium transition-colors ${
                  accountType === 'individual' ? 'bg-primary text-primary-foreground' : 'bg-muted/30 text-muted-foreground hover:text-foreground'
                }`}
              >
                Individual / Freelancer
              </button>
              <button
                type="button"
                onClick={() => setAccountType('company')}
                className={`flex-1 py-2.5 text-sm font-medium transition-colors ${
                  accountType === 'company' ? 'bg-primary text-primary-foreground' : 'bg-muted/30 text-muted-foreground hover:text-foreground'
                }`}
              >
                Company Account
              </button>
            </div>

            <form onSubmit={submit} className="space-y-4" noValidate>
              {/* Honeypot — kept off-screen for assistive tech and bots that read CSS. */}
              <div aria-hidden="true" style={{ position: 'absolute', left: '-10000px', top: 'auto', width: 1, height: 1, overflow: 'hidden' }}>
                <label>
                  Website (leave blank)
                  <input
                    type="text"
                    name="website"
                    tabIndex={-1}
                    autoComplete="off"
                    value={data.website}
                    onChange={(e) => setData('website', e.target.value)}
                  />
                </label>
              </div>

              {accountType === 'company' && (
                <>
                  <div className="space-y-2">
                    <Label>Company Type *</Label>
                    <Select value={data.company_type} onValueChange={(v) => setData('company_type', v)}>
                      <SelectTrigger>
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="customer_company">Purchasing Company</SelectItem>
                        <SelectItem value="training_company">Training Company</SelectItem>
                        <SelectItem value="hybrid">Hybrid (Purchasing &amp; Training)</SelectItem>
                      </SelectContent>
                    </Select>
                    <p className="text-xs text-muted-foreground">{companyTypeLabel(data.company_type)}</p>
                  </div>

                  <div className="space-y-2">
                    <Label>Company Name *</Label>
                    <div className="relative">
                      <Input
                        value={data.company_name}
                        onChange={(e) => setData('company_name', e.target.value)}
                        required
                        className={companyCheck === 'taken' ? 'border-destructive pr-9' : 'pr-9'}
                      />
                      <CheckIndicator status={companyCheck} />
                    </div>
                    {companyCheck === 'taken' && (
                      <p className="text-xs text-destructive">A company with this name is already registered.</p>
                    )}
                    {errors.company_name && <p className="text-xs text-destructive">{errors.company_name}</p>}
                  </div>

                  <div className="grid grid-cols-2 gap-4">
                    <div className="space-y-2">
                      <Label>Registration Number *</Label>
                      <Input value={data.registration_number} onChange={(e) => setData('registration_number', e.target.value)} required />
                    </div>
                    <div className="space-y-2">
                      <Label>VAT Number</Label>
                      <Input value={data.vat_number} onChange={(e) => setData('vat_number', e.target.value)} />
                    </div>
                  </div>

                  <div className="space-y-2">
                    <Label>Company Address *</Label>
                    <Textarea value={data.company_address} onChange={(e) => setData('company_address', e.target.value)} rows={3} required />
                  </div>

                  <div className="border-t border-border my-4" />
                </>
              )}

              <div className="space-y-2">
                <Label>{accountType === 'company' ? 'Account Admin Holder Name *' : 'Full Name *'}</Label>
                <Input value={data.full_name} onChange={(e) => setData('full_name', e.target.value)} required />
                {errors.full_name && <p className="text-xs text-destructive">{errors.full_name}</p>}
              </div>

              {accountType === 'individual' && (
                <div className="space-y-2">
                  <Label>Phone Number</Label>
                  <Input
                    type="tel"
                    value={data.phone}
                    onChange={(e) => setData('phone', e.target.value)}
                    placeholder="+44 7700 900123"
                    autoComplete="tel"
                    className={personalPhoneInvalid ? 'border-destructive' : ''}
                  />
                  <p className="text-xs text-muted-foreground">Optional — we'll only use this to contact you about your training.</p>
                  {personalPhoneInvalid && (
                    <p className="text-xs text-destructive">Enter a valid phone number (7–15 digits, optional country code).</p>
                  )}
                  {errors.phone && <p className="text-xs text-destructive">{errors.phone}</p>}
                </div>
              )}

              {accountType === 'company' && (
                <>
                  <div className="space-y-2">
                    <Label>Contact Phone Number *</Label>
                    <Input
                      type="tel"
                      value={data.contact_phone}
                      onChange={(e) => setData('contact_phone', e.target.value)}
                      required
                      placeholder="+44 7700 900123"
                      className={phoneInvalid ? 'border-destructive' : ''}
                    />
                    {phoneInvalid && (
                      <p className="text-xs text-destructive">Enter a valid phone number (7–15 digits, optional country code).</p>
                    )}
                    {errors.contact_phone && <p className="text-xs text-destructive">{errors.contact_phone}</p>}
                  </div>

                  <div className="grid grid-cols-2 gap-4">
                    <div className="space-y-2">
                      <Label>Accounts Contact Name *</Label>
                      <Input value={data.accounts_contact_name} onChange={(e) => setData('accounts_contact_name', e.target.value)} required />
                    </div>
                    <div className="space-y-2">
                      <Label>Accounts Contact Email *</Label>
                      <Input
                        type="email"
                        value={data.accounts_contact_email}
                        onChange={(e) => setData('accounts_contact_email', e.target.value)}
                        required
                        className={accountsEmailCheck === 'invalid' ? 'border-destructive' : ''}
                      />
                      {accountsEmailCheck === 'invalid' && (
                        <p className="text-xs text-destructive">Enter a valid email address.</p>
                      )}
                      {errors.accounts_contact_email && <p className="text-xs text-destructive">{errors.accounts_contact_email}</p>}
                    </div>
                  </div>

                  <div className="border-t border-border my-4" />
                </>
              )}

              <div className="space-y-2">
                <Label>Email *</Label>
                <div className="relative">
                  <Input
                    type="email"
                    value={data.email}
                    onChange={(e) => setData('email', e.target.value)}
                    required
                    autoComplete="username"
                    className={
                      emailCheck === 'taken' || emailCheck === 'invalid'
                        ? 'border-destructive pr-9'
                        : 'pr-9'
                    }
                  />
                  <CheckIndicator status={emailCheck} />
                </div>
                {emailCheck === 'invalid' && (
                  <p className="text-xs text-destructive">Enter a valid email address.</p>
                )}
                {emailCheck === 'taken' && (
                  <p className="text-xs text-destructive">
                    This email is already registered. <Link href={route('login')} className="underline">Sign in instead</Link>.
                  </p>
                )}
                {errors.email && <p className="text-xs text-destructive">{errors.email}</p>}
              </div>

              <div className="space-y-2">
                <Label>Password *</Label>
                <div className="relative">
                  <Input
                    type={showPassword ? 'text' : 'password'}
                    value={data.password}
                    onChange={(e) => setData('password', e.target.value)}
                    required
                    minLength={8}
                    autoComplete="new-password"
                  />
                  <button
                    type="button"
                    onClick={() => setShowPassword((v) => !v)}
                    className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                  >
                    {showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                  </button>
                </div>
                <p className="text-xs text-muted-foreground">Password must be at least 8 characters long.</p>
                {errors.password && <p className="text-xs text-destructive">{errors.password}</p>}
              </div>

              <div className="space-y-2">
                <Label>Confirm Password *</Label>
                <div className="relative">
                  <Input
                    type={showConfirmPassword ? 'text' : 'password'}
                    value={data.password_confirmation}
                    onChange={(e) => setData('password_confirmation', e.target.value)}
                    required
                    minLength={8}
                    autoComplete="new-password"
                  />
                  <button
                    type="button"
                    onClick={() => setShowConfirmPassword((v) => !v)}
                    className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
                  >
                    {showConfirmPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
                  </button>
                </div>
              </div>

              <div className="flex items-start gap-2">
                <Checkbox
                  id="terms"
                  checked={data.agreed_terms}
                  onCheckedChange={(v) => setData('agreed_terms', v === true)}
                />
                <label htmlFor="terms" className="text-sm text-muted-foreground leading-snug">
                  I agree to the{' '}
                  <Link href="/terms" className="text-primary hover:underline">Terms of Service</Link> and{' '}
                  <Link href="/privacy" className="text-primary hover:underline">Privacy Policy</Link>
                </label>
              </div>

              {accountType === 'company' && (
                <p className="text-xs text-muted-foreground bg-muted/50 rounded-lg p-3">
                  After submitting your account, this will go to our accounts department that will need to approve it. Upon approval, you'll receive an email to confirm this.
                </p>
              )}

              {accountType === 'individual' && (
                <p className="text-xs text-muted-foreground bg-muted/50 rounded-lg p-3">
                  As an individual, you can browse and book courses, access your certificates, and manage your training profile. You can be linked to a company later.
                </p>
              )}

              <Button
                type="submit"
                size="lg"
                className="w-full"
                disabled={
                  processing ||
                  emailCheck === 'checking' || emailCheck === 'taken' || emailCheck === 'invalid' ||
                  (accountType === 'individual' && personalPhoneInvalid) ||
                  (accountType === 'company' && (
                    companyCheck === 'checking' || companyCheck === 'taken' ||
                    phoneInvalid || accountsEmailCheck === 'invalid'
                  ))
                }
              >
                {processing ? (
                  <>
                    <Loader2 className="w-4 h-4 animate-spin mr-2" />
                    Submitting…
                  </>
                ) : accountType === 'individual' ? (
                  'Create Account'
                ) : (
                  'Submit Company Account Request'
                )}
              </Button>
            </form>

            <p className="text-sm text-muted-foreground text-center mt-6">
              Already have an account?{' '}
              <Link href={route('login')} className="text-primary hover:underline font-medium">Login</Link>
            </p>
          </div>
        </div>
        <Footer />
      </div>
    </>
  );
}

function CheckIndicator({ status }: { status: CheckStatus }) {
  if (status === 'idle') return null;
  const base = 'absolute right-3 top-1/2 -translate-y-1/2';
  if (status === 'checking') return <Loader2 className={`${base} w-4 h-4 animate-spin text-muted-foreground`} />;
  if (status === 'available') return <Check className={`${base} w-4 h-4 text-emerald-500`} />;
  return <X className={`${base} w-4 h-4 text-destructive`} />;
}

async function checkAvailability(field: 'email' | 'company_name', value: string): Promise<boolean> {
  const tokenEl = document.querySelector<HTMLMetaElement>('meta[name="csrf-token"]');
  const res = await fetch(route('register.check'), {
    method: 'POST',
    credentials: 'same-origin',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'X-Requested-With': 'XMLHttpRequest',
      ...(tokenEl ? { 'X-CSRF-TOKEN': tokenEl.content } : {}),
    },
    body: JSON.stringify({ field, value }),
  });
  if (!res.ok) throw new Error('check failed');
  const json = await res.json();
  return json.available === true;
}
