import { useState, type FormEvent } from 'react'

import { SettingsLayout } from './SettingsLayout'
import { Alert, Badge, Button, Card, CardBody, CardFooter, CardHeader, Input } from '@/components/ui'
import { useAuth } from '@/features/auth/AuthProvider'
import { ApiError, api } from '@/lib/api'
import type { DataResponse, NotificationPreferences, User } from '@/types/api'

/** Preference switches, grouped so the list reads as decisions not a data dump. */
const PREFERENCE_GROUPS: Array<{
  heading: string
  note?: string
  items: Array<{ key: string; label: string }>
}> = [
  {
    heading: 'Offers and negotiation',
    items: [
      { key: 'email_offers', label: 'Email me about offers and counter-offers' },
      { key: 'inapp_offers', label: 'Show offer activity in my notifications' },
    ],
  },
  {
    heading: 'Orders and transfers',
    items: [
      { key: 'email_orders', label: 'Email me about purchases and sales' },
      { key: 'email_transfers', label: 'Email me about transfer progress' },
      { key: 'whatsapp_orders', label: 'Send order updates over WhatsApp' },
    ],
  },
  {
    heading: 'Watchlist and discovery',
    items: [
      { key: 'email_watchlist', label: 'Email me when a watched domain changes' },
      { key: 'email_weekly_digest', label: 'Send me a weekly digest of new listings' },
    ],
  },
]

export function ProfileSettingsPage() {
  const { user, setUser } = useAuth()

  const [form, setForm] = useState({
    name: user?.name ?? '',
    phone: user?.phone ?? '',
    bio: user?.profile?.bio ?? '',
    city: user?.profile?.city ?? '',
    country_code: user?.profile?.country_code ?? '',
    website_url: user?.profile?.website_url ?? '',
    company_name: user?.profile?.company_name ?? '',
  })

  const [preferences, setPreferences] = useState<NotificationPreferences>(
    user?.profile?.notification_preferences ?? {},
  )

  const [error, setError] = useState<ApiError | null>(null)
  const [savedMessage, setSavedMessage] = useState<string | null>(null)
  const [isSaving, setIsSaving] = useState(false)

  const save = async (payload: Record<string, unknown>) => {
    setError(null)
    setSavedMessage(null)
    setIsSaving(true)

    try {
      const response = await api.patch<DataResponse<User> & { message: string }>('/account', payload)
      setUser(response.data)
      setSavedMessage(response.message)
    } catch (caught) {
      if (caught instanceof ApiError) {
        setError(caught)
      } else {
        throw caught
      }
    } finally {
      setIsSaving(false)
    }
  }

  const handleDetailsSubmit = (event: FormEvent) => {
    event.preventDefault()

    void save({
      name: form.name,
      // An empty field means "clear this", which the API expresses as null.
      phone: form.phone === '' ? null : form.phone,
      bio: form.bio === '' ? null : form.bio,
      city: form.city === '' ? null : form.city,
      country_code: form.country_code === '' ? null : form.country_code.toUpperCase(),
      website_url: form.website_url === '' ? null : form.website_url,
      company_name: form.company_name === '' ? null : form.company_name,
    })
  }

  const togglePreference = (key: string, value: boolean) => {
    const next = { ...preferences, [key]: value }
    setPreferences(next)

    // Only the changed key is sent; the API merges it over what is stored.
    void save({ notification_preferences: { [key]: value } })
  }

  return (
    <SettingsLayout title="Profile" description="How you appear across the marketplace.">
      {savedMessage !== null && <Alert tone="success">{savedMessage}</Alert>}
      {error !== null && !error.isValidation && (
        <Alert tone="error" title="Could not save">
          {error.message}
        </Alert>
      )}

      <Card>
        <CardHeader
          title="Your details"
          description="Your name is shown on offers you make and listings you own."
        />

        <form onSubmit={handleDetailsSubmit}>
          <CardBody className="flex flex-col gap-5">
            <div className="grid gap-5 sm:grid-cols-2">
              <Input
                label="Full name"
                value={form.name}
                onChange={(event) => setForm({ ...form, name: event.target.value })}
                required
                error={error?.errorFor('name')}
              />

              <div className="flex flex-col gap-1.5">
                <span className="text-sm font-medium text-text-primary">Email address</span>
                <div className="flex h-10 items-center gap-2 rounded-md border border-border-subtle bg-surface-sunken px-3">
                  <span className="truncate text-sm text-text-secondary">{user?.email}</span>
                  {user?.email_verified === true ? (
                    <Badge tone="positive">Verified</Badge>
                  ) : (
                    <Badge tone="caution">Unverified</Badge>
                  )}
                </div>
                {/*
                  Changing an email address is not a profile edit: it re-opens
                  verification and is a common account-takeover vector, so it
                  gets its own audited flow rather than riding along here.
                */}
                <p className="text-sm text-text-muted">
                  Email changes are handled separately for security.
                </p>
              </div>

              <Input
                label="Phone number"
                value={form.phone}
                onChange={(event) => setForm({ ...form, phone: event.target.value })}
                error={error?.errorFor('phone')}
                hint={
                  user?.phone_verified === true
                    ? 'Verified. Changing this will require verifying again.'
                    : 'Optional. Used for account recovery and order updates.'
                }
              />

              <Input
                label="Company"
                value={form.company_name}
                onChange={(event) => setForm({ ...form, company_name: event.target.value })}
                error={error?.errorFor('company_name')}
              />

              <Input
                label="City"
                value={form.city}
                onChange={(event) => setForm({ ...form, city: event.target.value })}
                error={error?.errorFor('city')}
              />

              <Input
                label="Country code"
                value={form.country_code}
                onChange={(event) => setForm({ ...form, country_code: event.target.value })}
                maxLength={2}
                placeholder="NP"
                error={error?.errorFor('country_code')}
                hint="Two-letter ISO country code."
              />
            </div>

            <Input
              label="Website"
              type="url"
              value={form.website_url}
              onChange={(event) => setForm({ ...form, website_url: event.target.value })}
              placeholder="https://"
              error={error?.errorFor('website_url')}
            />

            <div className="flex flex-col gap-1.5">
              <label htmlFor="bio" className="text-sm font-medium text-text-primary">
                About you
              </label>
              <textarea
                id="bio"
                rows={4}
                value={form.bio}
                onChange={(event) => setForm({ ...form, bio: event.target.value })}
                maxLength={1000}
                className="w-full rounded-md border border-border-control bg-surface px-3 py-2.5 text-sm text-text-primary transition-colors duration-150 placeholder:text-text-muted hover:border-border-strong focus:border-border-accent focus:outline-none"
                placeholder="A short introduction shown on your seller profile."
              />
              <p className="text-sm text-text-muted">{form.bio.length} of 1000 characters</p>
            </div>
          </CardBody>

          <CardFooter>
            <Button type="submit" isLoading={isSaving}>
              Save changes
            </Button>
          </CardFooter>
        </form>
      </Card>

      <Card>
        <CardHeader
          title="Notifications"
          description="Choose how we reach you. Security alerts are always sent."
        />

        <CardBody className="flex flex-col gap-6">
          {PREFERENCE_GROUPS.map((group) => (
            <fieldset key={group.heading}>
              <legend className="text-sm font-semibold text-text-primary">{group.heading}</legend>

              <div className="mt-3 flex flex-col gap-3">
                {group.items.map((item) => (
                  <label
                    key={item.key}
                    className="flex items-center justify-between gap-4 text-sm text-text-secondary"
                  >
                    {item.label}
                    <input
                      type="checkbox"
                      checked={preferences[item.key] ?? false}
                      onChange={(event) => togglePreference(item.key, event.target.checked)}
                      className="size-4 shrink-0 rounded border-border-control accent-[var(--accent-solid)]"
                    />
                  </label>
                ))}
              </div>
            </fieldset>
          ))}

          <p className="border-t border-border-subtle pt-4 text-sm text-text-muted">
            Notifications about money in flight — an accepted offer, a transfer starting, a payout
            released — are always sent, because you need to know about them.
          </p>
        </CardBody>
      </Card>
    </SettingsLayout>
  )
}
