import { Store } from 'lucide-react'
import { useState, type FormEvent } from 'react'
import { Link } from 'react-router-dom'

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

/**
 * Seller setup.
 *
 * The same account buys and sells, so this is a capability the user switches on
 * rather than a second registration. That framing is deliberate throughout the
 * copy here.
 */
export function SellerSettingsPage() {
  const { user, refresh } = useAuth()
  const seller = user?.seller ?? null

  return (
    <SettingsLayout
      title="Selling"
      description="Your public seller identity and payout currency."
    >
      {seller === null ? (
        <SellerOnboarding onDone={refresh} emailVerified={user?.email_verified ?? false} />
      ) : (
        <SellerDetails seller={seller} onSaved={refresh} />
      )}
    </SettingsLayout>
  )
}

function SellerOnboarding({
  onDone,
  emailVerified,
}: {
  onDone: () => Promise<void>
  emailVerified: boolean
}) {
  const [displayName, setDisplayName] = useState('')
  const [error, setError] = useState<ApiError | null>(null)
  const [isSubmitting, setIsSubmitting] = useState(false)

  const submit = async () => {
    setError(null)
    setIsSubmitting(true)

    try {
      await api.post('/account/seller', displayName === '' ? {} : { display_name: displayName })
      await onDone()
    } catch (caught) {
      if (caught instanceof ApiError) {
        setError(caught)
      } else {
        throw caught
      }
    } finally {
      setIsSubmitting(false)
    }
  }

  return (
    <>
      {error !== null && (
        <Alert tone="error" title="Could not set up selling">
          {error.message}
        </Alert>
      )}

      {/*
        Selling creates an obligation to a buyer, so the account has to have
        proved it can receive mail first. Said here rather than only enforced by
        a server error the user has to guess at.
      */}
      {!emailVerified && (
        <Alert tone="warning" title="Confirm your email first">
          Selling requires a confirmed email address, so buyers can reach you about a sale.{' '}
          <Link to="/verify-email/pending" className="underline underline-offset-2">
            Send a new confirmation link
          </Link>
          .
        </Alert>
      )}

      <Card>
        <CardBody>
          <EmptyState
            icon={<Store className="size-5" />}
            title="Start selling on Domainsansar"
            description="Selling uses the account you already have. Add a public seller name, then verify ownership of the domains you want to list."
            action={
              <div className="flex w-full max-w-sm flex-col gap-3">
                <Input
                  label="Public seller name"
                  labelHidden
                  value={displayName}
                  onChange={(event) => setDisplayName(event.target.value)}
                  placeholder="Your seller name (optional)"
                  error={error?.errorFor('display_name')}
                />
                <Button
                  size="lg"
                  fullWidth
                  isLoading={isSubmitting}
                  disabled={!emailVerified}
                  onClick={() => void submit()}
                >
                  Set up selling
                </Button>
              </div>
            }
          />
        </CardBody>
      </Card>
    </>
  )
}

function SellerDetails({
  seller,
  onSaved,
}: {
  seller: SellerProfile
  onSaved: () => Promise<void>
}) {
  const [form, setForm] = useState({
    display_name: seller.display_name,
    handle: seller.handle,
    about: seller.about ?? '',
    support_email: seller.support_email ?? '',
  })

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

  const submit = async (event: FormEvent) => {
    event.preventDefault()
    setError(null)
    setNotice(null)
    setIsSaving(true)

    try {
      const response = await api.patch<DataResponse<SellerProfile> & { message: string }>(
        '/account/seller',
        {
          display_name: form.display_name,
          handle: form.handle,
          about: form.about === '' ? null : form.about,
          support_email: form.support_email === '' ? null : form.support_email,
        },
      )

      setNotice(response.message)
      await onSaved()
    } catch (caught) {
      if (caught instanceof ApiError) {
        setError(caught)
      } else {
        throw caught
      }
    } finally {
      setIsSaving(false)
    }
  }

  return (
    <>
      {notice !== null && <Alert tone="success">{notice}</Alert>}
      {error !== null && !error.isValidation && (
        <Alert tone="error" title="Could not save">
          {error.message}
        </Alert>
      )}

      {/*
        A seller who cannot list needs to know, and needs a route to support.
        The reason is deliberately not shown: the underlying risk signals stay
        internal, and exposing them would teach an abuser what to avoid.
      */}
      {!seller.can_list && (
        <Alert tone="warning" title="Listing is currently paused on this account">
          You cannot create or activate listings right now.{' '}
          <Link to="/contact" className="underline underline-offset-2">
            Contact support
          </Link>{' '}
          and we will look into it.
        </Alert>
      )}

      <Card>
        <CardHeader
          title="Seller profile"
          description="Shown to buyers on your listings and your public seller page."
          action={<Badge tone="accent">{seller.tier_label}</Badge>}
        />

        <form onSubmit={submit}>
          <CardBody className="flex flex-col gap-5">
            <Input
              label="Public seller name"
              value={form.display_name}
              onChange={(event) => setForm({ ...form, display_name: event.target.value })}
              required
              error={error?.errorFor('display_name')}
            />

            <Input
              label="Handle"
              value={form.handle}
              onChange={(event) => setForm({ ...form, handle: event.target.value.toLowerCase() })}
              required
              error={error?.errorFor('handle')}
              hint={`Your public page: domainsansar.com/seller/${form.handle}`}
            />

            <Input
              label="Support email"
              type="email"
              value={form.support_email}
              onChange={(event) => setForm({ ...form, support_email: event.target.value })}
              error={error?.errorFor('support_email')}
              hint="Optional. Shown to buyers who have an active order with you."
            />

            <div className="flex flex-col gap-1.5">
              <label htmlFor="seller-about" className="text-sm font-medium text-text-primary">
                About your portfolio
              </label>
              <textarea
                id="seller-about"
                rows={4}
                value={form.about}
                onChange={(event) => setForm({ ...form, about: event.target.value })}
                maxLength={2000}
                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"
              />
            </div>
          </CardBody>

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

      <Card>
        <CardHeader
          title="Seller verification"
          description="Verified sellers convert better and pay lower commission."
        />

        <CardBody className="flex flex-col gap-3">
          {[
            {
              label: 'Identity verified',
              status: seller.identity_status,
              note: 'Confirms you are who you say you are.',
            },
            {
              label: 'Payment verified',
              status: seller.payment_status,
              note: 'Confirms where your payouts should go.',
            },
          ].map((row) => (
            <div
              key={row.label}
              className="flex items-center justify-between gap-4 rounded-lg border border-border-subtle px-4 py-3"
            >
              <div>
                <p className="text-sm font-medium text-text-primary">{row.label}</p>
                <p className="text-sm text-text-secondary">{row.note}</p>
              </div>

              {row.status === 'verified' ? (
                <Badge tone="positive">Verified</Badge>
              ) : row.status === 'pending' ? (
                <Badge tone="caution">In review</Badge>
              ) : (
                <Badge tone="neutral">Not started</Badge>
              )}
            </div>
          ))}

          <p className="text-sm text-text-muted">
            Identity and payment verification arrive with payouts. Domain ownership is verified
            per domain, when you add it.
          </p>
        </CardBody>
      </Card>
    </>
  )
}
