'use client'

import Link from 'next/link'
import { useState } from 'react'
import { useSearchParams } from 'next/navigation'
import { apiFetch } from '@/lib/api'
import PublicShell from '@/components/layout/PublicShell'
import { marketplaceUrl } from '@/lib/urls'

type SignupForm = {
  firstName: string
  lastName: string
  email: string
  password: string
  confirmPassword: string
  companyName: string
  companyPhone: string
  city: string
  country: string
  plan: 'STARTER' | 'GROWTH' | 'PRO'
  billingPeriod: 'MONTHLY' | 'ANNUAL'
  currency: 'MAD' | 'USD' | 'EUR'
  paymentProvider: 'AMANPAY' | 'PAYPAL'
}

type CompletedSignup = {
  companyName: string
  email: string
  emailWarning?: string | null
}

type SignupResponse = {
  companyId: string
  companyName: string
  slug: string
  trialEndsAt: string | null
  nextStep: string
  emailDelivery?: {
    attempted: boolean
    success: boolean
    error: string | null
  } | null
}

export default function SignUpPage() {
  const searchParams = useSearchParams()
  const initialPlan = normalizePlan(searchParams.get('plan'))
  const initialBillingPeriod = normalizeBillingPeriod(searchParams.get('billing'))
  const initialCurrency = normalizeCurrency(searchParams.get('currency'))
  const [step, setStep] = useState(1)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [completedSignup, setCompletedSignup] = useState<CompletedSignup | null>(null)
  const [form, setForm] = useState<SignupForm>({
    firstName: '',
    lastName: '',
    email: '',
    password: '',
    confirmPassword: '',
    companyName: '',
    companyPhone: '',
    city: '',
    country: '',
    plan: initialPlan,
    billingPeriod: initialBillingPeriod,
    currency: initialCurrency,
    paymentProvider: 'AMANPAY',
  })

  async function submitSignup() {
    if (form.password.length < 8) {
      setError('Choose a password with at least 8 characters.')
      return
    }

    if (form.password !== form.confirmPassword) {
      setError('Passwords do not match.')
      return
    }

    setLoading(true)
    setError(null)

    try {
      const response = await apiFetch<SignupResponse>('/auth/company/signup', {
        method: 'POST',
        body: JSON.stringify({
          firstName: form.firstName,
          lastName: form.lastName,
          email: form.email,
          password: form.password,
          companyName: form.companyName,
          companyPhone: form.companyPhone || undefined,
          city: form.city || undefined,
          country: form.country || undefined,
          plan: form.plan,
          billingPeriod: form.billingPeriod,
          currency: form.currency,
          paymentProvider: form.paymentProvider,
        }),
      })

      setCompletedSignup({
        companyName: form.companyName,
        email: form.email,
        emailWarning: getEmailWarning(response.emailDelivery),
      })
    } catch (err) {
      setError(getErrorMessage(err, 'Could not create workspace'))
    } finally {
      setLoading(false)
    }
  }

  if (completedSignup) {
    return (
      <PublicShell>
        <main className="flex-1 px-4 py-16">
          <div className="mx-auto max-w-2xl rounded-[2rem] border border-slate-200 bg-white p-10 shadow-sm">
            <Link href={marketplaceUrl} className="text-xs font-semibold uppercase tracking-[0.24em] text-blue-600">RentalDriveGo</Link>
            <h1 className="mt-4 text-4xl font-black tracking-tight text-slate-900">Workspace ready</h1>
            <p className="mt-4 text-base leading-7 text-slate-600">
              <span className="font-semibold text-slate-900">{completedSignup.companyName}</span> is now active and the owner email
              <span className="font-semibold text-slate-900"> {completedSignup.email}</span> has been registered.
            </p>
            {completedSignup.emailWarning ? (
              <div className="mt-6 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800">
                {completedSignup.emailWarning}
              </div>
            ) : null}
            <div className="mt-8 flex flex-col gap-3 sm:flex-row">
              <Link href="/dashboard" className="btn-primary justify-center">
                Enter dashboard
              </Link>
              <Link href="/sign-in" className="btn-secondary justify-center">
                Sign in on another device
              </Link>
            </div>
          </div>
        </main>
      </PublicShell>
    )
  }

  return (
    <PublicShell>
      <main className="px-4 py-12">
        <div className="mx-auto max-w-3xl space-y-8">
          <div className="text-center">
            <Link href={marketplaceUrl} className="text-xs font-semibold uppercase tracking-[0.24em] text-blue-600">RentalDriveGo</Link>
            <h1 className="mt-3 text-5xl font-black tracking-tight text-slate-900">Launch your rental workspace</h1>
            <p className="mt-4 text-base leading-7 text-slate-600">Create the owner account and start your 14-day free trial.</p>
          </div>

          <div className="grid gap-3 sm:grid-cols-4">
            {['Account', 'Company', 'Plan', 'Verify'].map((label, index) => (
              <div key={label} className={`rounded-full px-4 py-2 text-center text-sm font-semibold ${index + 1 <= step ? 'bg-slate-900 text-white' : 'border border-slate-200 bg-white text-slate-500'}`}>
                {label}
              </div>
            ))}
          </div>

          <div className="rounded-[2rem] border border-slate-200 bg-white p-8 shadow-sm">
            {error ? <div className="mb-6 rounded-2xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">{error}</div> : null}

            {step === 1 ? (
              <div className="space-y-5">
                <SectionIntro title="Owner account" body="This becomes the primary owner account for the company workspace." />
                <div className="grid gap-4 sm:grid-cols-2">
                  <LabeledInput label="First name" value={form.firstName} onChange={(value) => setForm((current) => ({ ...current, firstName: value }))} />
                  <LabeledInput label="Last name" value={form.lastName} onChange={(value) => setForm((current) => ({ ...current, lastName: value }))} />
                </div>
                <LabeledInput label="Email" type="email" value={form.email} onChange={(value) => setForm((current) => ({ ...current, email: value }))} />
                <div className="grid gap-4 sm:grid-cols-2">
                  <LabeledInput label="Password" type="password" value={form.password} onChange={(value) => setForm((current) => ({ ...current, password: value }))} />
                  <LabeledInput label="Confirm password" type="password" value={form.confirmPassword} onChange={(value) => setForm((current) => ({ ...current, confirmPassword: value }))} />
                </div>
                <p className="text-xs text-slate-500">Use at least 8 characters for your company owner account.</p>
                <div className="flex justify-end">
                  <button type="button" onClick={() => setStep(2)} className="btn-primary">Continue</button>
                </div>
              </div>
            ) : null}

            {step === 2 ? (
              <div className="space-y-5">
                <SectionIntro title="Company details" body="We’ll use these details for your trial workspace and public marketplace profile." />
                <LabeledInput label="Company name" value={form.companyName} onChange={(value) => setForm((current) => ({ ...current, companyName: value }))} />
                <div className="grid gap-4 sm:grid-cols-2">
                  <LabeledInput label="Phone" value={form.companyPhone} onChange={(value) => setForm((current) => ({ ...current, companyPhone: value }))} />
                  <LabeledInput label="Country" value={form.country} onChange={(value) => setForm((current) => ({ ...current, country: value }))} />
                </div>
                <LabeledInput label="City" value={form.city} onChange={(value) => setForm((current) => ({ ...current, city: value }))} />
                <NavActions onBack={() => setStep(1)} onNext={() => setStep(3)} />
              </div>
            ) : null}

            {step === 3 ? (
              <div className="space-y-5">
                <SectionIntro title="Choose your plan" body="Your workspace starts immediately on a 14-day free trial in your preferred billing currency." />
                <div className="grid gap-4 sm:grid-cols-3">
                  {['STARTER', 'GROWTH', 'PRO'].map((plan) => (
                    <button
                      key={plan}
                      type="button"
                      onClick={() => setForm((current) => ({ ...current, plan: plan as SignupForm['plan'] }))}
                      className={`rounded-3xl border p-5 text-left ${form.plan === plan ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-200 bg-white text-slate-900'}`}
                    >
                      <p className="text-xs font-semibold uppercase tracking-[0.16em]">{plan}</p>
                      <p className="mt-3 text-sm opacity-80">{plan === 'STARTER' ? 'Core fleet, offers, and bookings.' : plan === 'GROWTH' ? 'Featured marketplace placement and more room to scale.' : 'Full white-label and premium controls.'}</p>
                    </button>
                  ))}
                </div>
                <div className="grid gap-4 sm:grid-cols-3">
                  <LabeledSelect label="Billing period" value={form.billingPeriod} options={['MONTHLY', 'ANNUAL']} onChange={(value) => setForm((current) => ({ ...current, billingPeriod: value as SignupForm['billingPeriod'] }))} />
                  <LabeledSelect label="Currency" value={form.currency} options={['MAD', 'USD', 'EUR']} onChange={(value) => setForm((current) => ({ ...current, currency: value as SignupForm['currency'] }))} />
                  <LabeledSelect label="Primary provider" value={form.paymentProvider} options={['AMANPAY', 'PAYPAL']} onChange={(value) => setForm((current) => ({ ...current, paymentProvider: value as SignupForm['paymentProvider'] }))} />
                </div>
                <NavActions onBack={() => setStep(2)} onNext={() => setStep(4)} />
              </div>
            ) : null}

            {step === 4 ? (
              <div className="space-y-5">
                <SectionIntro title="Review and launch" body="We’ll create the company workspace immediately and start the 14-day trial with the plan you selected." />
                <div className="rounded-3xl border border-slate-200 bg-slate-50 p-5 text-sm text-slate-600">
                  <p><span className="font-semibold text-slate-900">Workspace:</span> {form.companyName || 'Your company'}</p>
                  <p className="mt-2"><span className="font-semibold text-slate-900">Plan:</span> {form.plan} · {form.billingPeriod} · {form.currency}</p>
                  <p className="mt-2"><span className="font-semibold text-slate-900">Owner email:</span> {form.email || '—'}</p>
                </div>
                <NavActions
                  onBack={() => setStep(3)}
                  onNext={submitSignup}
                  loading={loading}
                  nextLabel="Create workspace"
                />
              </div>
            ) : null}
          </div>
        </div>
      </main>
    </PublicShell>
  )
}

function SectionIntro({ title, body }: { title: string; body: string }) {
  return (
    <div>
      <h2 className="text-xl font-semibold text-slate-900">{title}</h2>
      <p className="mt-2 text-sm leading-7 text-slate-500">{body}</p>
    </div>
  )
}

function getEmailWarning(emailDelivery: SignupResponse['emailDelivery']) {
  if (!emailDelivery) return null
  if (emailDelivery.success) return null
  if (emailDelivery.attempted) {
    return `The account was created, but the confirmation email could not be delivered${emailDelivery.error ? `: ${emailDelivery.error}` : '.'}`
  }
  return 'The account was created, but email sending is not configured on this environment yet.'
}

function getErrorMessage(error: unknown, fallback: string) {
  if (error instanceof Error && error.message) return error.message
  return fallback
}

function LabeledInput({ label, value, onChange, type = 'text' }: { label: string; value: string; onChange: (value: string) => void; type?: string }) {
  return (
    <label className="block">
      <span className="mb-1.5 block text-sm font-medium text-slate-700">{label}</span>
      <input type={type} className="input-field" value={value} onChange={(event) => onChange(event.target.value)} />
    </label>
  )
}

function LabeledSelect({ label, value, options, onChange }: { label: string; value: string; options: string[]; onChange: (value: string) => void }) {
  return (
    <label className="block">
      <span className="mb-1.5 block text-sm font-medium text-slate-700">{label}</span>
      <select className="input-field" value={value} onChange={(event) => onChange(event.target.value)}>
        {options.map((option) => (
          <option key={option} value={option}>{option}</option>
        ))}
      </select>
    </label>
  )
}

function NavActions({ onBack, onNext, loading = false, nextLabel = 'Continue' }: { onBack?: () => void; onNext: () => void; loading?: boolean; nextLabel?: string }) {
  return (
    <div className="flex gap-3">
      {onBack ? (
        <button type="button" onClick={onBack} className="btn-secondary flex-1 justify-center">
          Back
        </button>
      ) : null}
      <button type="button" onClick={onNext} disabled={loading} className="btn-primary flex-1 justify-center disabled:cursor-not-allowed disabled:opacity-60">
        {loading ? 'Working…' : nextLabel}
      </button>
    </div>
  )
}

function normalizePlan(value: string | null): SignupForm['plan'] {
  if (value === 'GROWTH' || value === 'PRO' || value === 'STARTER') return value
  return 'STARTER'
}

function normalizeBillingPeriod(value: string | null): SignupForm['billingPeriod'] {
  return value === 'ANNUAL' ? 'ANNUAL' : 'MONTHLY'
}

function normalizeCurrency(value: string | null): SignupForm['currency'] {
  if (value === 'USD' || value === 'EUR' || value === 'MAD') return value
  return 'MAD'
}
