import { useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import {
  AlertCircle,
  ArrowRight,
  Check,
  Clock,
  Copy,
  CreditCard,
  Crown,
  FolderTree,
  Loader2,
  Mail,
  MessageSquareText,
  Palette,
  Pencil,
  Plug,
  RefreshCw,
  Server,
  Shield,
  UserCog,
  X,
} from 'lucide-react'
import { PageMeta } from '@/components/common/PageMeta'
import { accountsApi } from '@/api/accounts'
import type { Account, AccountInvite, AccountMember } from '@/types'
import { TransferOwnershipModal } from '@/components/account/TransferOwnershipModal'
import { LeaveAccountModal } from '@/components/account/LeaveAccountModal'
import { DeleteAccountModal } from '@/components/account/DeleteAccountModal'
import { Button } from '@/components/ui/Button'
import { ConfirmButton } from '@/components/common/ConfirmButton'
import { Spinner } from '@/components/common/Spinner'
import { cn } from '@/lib/utils'
import { usePermissions } from '@/hooks/usePermissions'
import { useSubscription } from '@/hooks/useSubscription'
import { SeatCounterWidget } from '@/components/admin/SeatCounterWidget'
import { useAuthStore } from '@/store/authStore'
import { CheckoutButton } from '@/components/subscription/CheckoutButton'
import { toast } from '@/lib/toast'

/* ── Building blocks ─────────────────────────────────────────────────────── */

function SectionLabel({ children }: { children: React.ReactNode }) {
  return (
    <h2 className="text-[0.6875rem] font-mono uppercase tracking-[0.12em] text-text-muted">
      {children}
    </h2>
  )
}

function UsageRow({
  label,
  current,
  max,
}: {
  label: string
  current: number
  max: number | null
}) {
  const isUnlimited = max === null
  const percentage = isUnlimited ? 0 : Math.min((current / max) * 100, 100)
  const isAtLimit = !isUnlimited && current >= max
  const isNearLimit = !isUnlimited && percentage >= 80

  const numeralColor = isAtLimit
    ? 'text-danger'
    : isNearLimit
      ? 'text-warning'
      : 'text-foreground'
  const barColor = isAtLimit ? 'bg-danger' : isNearLimit ? 'bg-warning' : 'bg-primary'

  return (
    <div className="grid grid-cols-[8rem_1fr_auto] items-center gap-4 py-1.5">
      <span className="text-sm text-muted-foreground">{label}</span>
      <div className="h-1 overflow-hidden rounded-full bg-muted">
        {!isUnlimited && (
          <div className={cn('h-full rounded-full', barColor)} style={{ width: `${percentage}%` }} />
        )}
      </div>
      <span className="text-sm tabular-nums">
        <span className={numeralColor}>{current}</span>
        <span className="text-muted-foreground"> / {isUnlimited ? '∞' : max}</span>
      </span>
    </div>
  )
}

interface SettingsRowProps {
  to: string
  icon: React.ReactNode
  title: string
  description: string
  status?: { label: string; tone: 'positive' | 'neutral' | 'warning' }
}

function SettingsRow({ to, icon, title, description, status }: SettingsRowProps) {
  return (
    <Link
      to={to}
      className={cn(
        'group flex items-center gap-3 py-2.5 -mx-2 px-2 rounded-md',
        'transition-colors hover:bg-card-hover'
      )}
    >
      <span className="text-muted-foreground shrink-0">{icon}</span>
      <div className="min-w-0 flex-1">
        <div className="text-sm font-medium text-foreground">{title}</div>
        <div className="text-xs text-muted-foreground truncate">{description}</div>
      </div>
      {status && (
        <span
          className={cn(
            'rounded-full px-2 py-0.5 text-[11px] font-medium shrink-0',
            status.tone === 'positive' && 'bg-success-dim text-success',
            status.tone === 'neutral' && 'bg-muted text-muted-foreground',
            status.tone === 'warning' && 'bg-warning-dim text-warning'
          )}
        >
          {status.label}
        </span>
      )}
      <ArrowRight className="h-4 w-4 text-muted-foreground/50 transition-all group-hover:translate-x-0.5 group-hover:text-foreground" />
    </Link>
  )
}

function formatShortDate(value: string | null | undefined) {
  if (!value) return 'Never'
  return new Date(value).toLocaleDateString()
}

function planLabel(plan: string) {
  return plan.charAt(0).toUpperCase() + plan.slice(1)
}

/* ── Page ────────────────────────────────────────────────────────────────── */

export function AccountSettingsPage() {
  const { isAccountOwner } = usePermissions()
  const { plan, limits, usage } = useSubscription()
  const subscription = useAuthStore((s) => s.subscription)
  const user = useAuthStore((s) => s.user)
  const refreshUser = useAuthStore((s) => s.fetchUser)

  const [account, setAccount] = useState<Account | null>(null)
  const [members, setMembers] = useState<AccountMember[]>([])
  const [invites, setInvites] = useState<AccountInvite[]>([])
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [copiedCode, setCopiedCode] = useState(false)

  const [isEditingName, setIsEditingName] = useState(false)
  const [editedName, setEditedName] = useState('')
  const [isSavingName, setIsSavingName] = useState(false)

  const [showTransferModal, setShowTransferModal] = useState(false)
  const [showLeaveModal, setShowLeaveModal] = useState(false)
  const [showDeleteModal, setShowDeleteModal] = useState(false)

  const [inviteEmail, setInviteEmail] = useState('')
  const [inviteRole, setInviteRole] = useState('engineer')
  const [isInviting, setIsInviting] = useState(false)
  const [resendingId, setResendingId] = useState<string | null>(null)

  useEffect(() => {
    loadData()
  }, []) // eslint-disable-line react-hooks/exhaustive-deps -- initial account load; mutations call loadData explicitly

  const loadData = async () => {
    setIsLoading(true)
    setError(null)
    try {
      const accountData = await accountsApi.getMyAccount()
      setAccount(accountData)
      setEditedName(accountData.name)

      if (isAccountOwner) {
        const [membersData, invitesData] = await Promise.all([
          accountsApi.getMembers(),
          accountsApi.getInvites(),
        ])
        setMembers(membersData)
        setInvites(invitesData)
      }
    } catch (err) {
      setError('Failed to load account information')
      console.error(err)
    } finally {
      setIsLoading(false)
    }
  }

  const pendingInvites = useMemo(() => invites.filter((invite) => !invite.used_at), [invites])
  const ownerMember = useMemo(
    () => members.find((member) => member.account_role === 'owner') ?? null,
    [members]
  )
  const memberCount = members.length || (isAccountOwner ? 1 : undefined)

  const handleCopyDisplayCode = async () => {
    if (!account?.display_code) return
    await navigator.clipboard.writeText(account.display_code)
    setCopiedCode(true)
    toast.success('Display code copied')
    setTimeout(() => setCopiedCode(false), 2000)
  }

  const handleSaveName = async () => {
    if (!editedName.trim() || editedName === account?.name) {
      setIsEditingName(false)
      return
    }
    setIsSavingName(true)
    try {
      const updated = await accountsApi.updateMyAccount({ name: editedName.trim() })
      setAccount(updated)
      setIsEditingName(false)
      toast.success('Account name updated')
      await refreshUser()
    } catch (err) {
      toast.error('Failed to update account name')
      console.error('Failed to update account name:', err)
    } finally {
      setIsSavingName(false)
    }
  }

  const handleInvite = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!inviteEmail.trim()) return

    setIsInviting(true)
    try {
      await accountsApi.createInvite({ email: inviteEmail.trim(), role: inviteRole })
      toast.success(`Invitation sent to ${inviteEmail}`)
      setInviteEmail('')
      const invitesData = await accountsApi.getInvites()
      setInvites(invitesData)
    } catch (err) {
      const resp = (err as {
        response?: {
          status?: number
          data?: { detail?: { code?: string; role?: string; current?: number; limit?: number } }
        }
      }).response
      if (resp?.status === 402 && resp?.data?.detail?.code === 'seat_limit_exceeded') {
        const d = resp.data.detail
        const label = d.role === 'l1_tech' ? 'L1' : 'Engineer'
        toast.warning(
          `${label} seats full: ${d.current}/${d.limit}. Upgrade your plan to add more.`,
        )
      } else {
        toast.error('Failed to send invitation')
        console.error(err)
      }
    } finally {
      setIsInviting(false)
    }
  }

  const handleResendInvite = async (inviteId: string) => {
    setResendingId(inviteId)
    try {
      await accountsApi.resendInvite(inviteId)
      toast.success('Invite resent with a new code')
      const invitesData = await accountsApi.getInvites()
      setInvites(invitesData)
    } catch {
      toast.error('Failed to resend invite')
    } finally {
      setResendingId(null)
    }
  }

  const handleRemoveMember = async (userId: string) => {
    try {
      await accountsApi.removeMember(userId)
      setMembers((current) => current.filter((member) => member.id !== userId))
      toast.success('Member removed')
      await refreshUser()
    } catch (err) {
      toast.error('Failed to remove member')
      console.error('Failed to remove member:', err)
    }
  }

  if (isLoading) {
    return (
      <div className="flex justify-center py-12">
        <Spinner />
      </div>
    )
  }

  if (error) {
    return (
      <div className="rounded-md border border-danger/20 bg-danger-dim p-4 text-danger">
        <div className="flex items-center gap-2">
          <AlertCircle className="h-5 w-5" />
          {error}
        </div>
      </div>
    )
  }

  const sub = subscription?.subscription
  const ownerName = ownerMember?.name ?? (user?.account_role === 'owner' ? user.name : null)
  const inputClass = cn(
    'rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground',
    'placeholder:text-muted-foreground',
    'focus:border-primary/40 focus:outline-hidden focus:ring-1 focus:ring-primary/20'
  )

  return (
    <>
      <PageMeta title="Account Settings" />
      <div className="mx-auto max-w-3xl space-y-10">
        {/* ── Header ─────────────────────────────────────────────────────── */}
        <header className="space-y-3">
          <div className="flex items-baseline gap-3">
            {isEditingName ? (
              <div className="flex items-center gap-2">
                <input
                  type="text"
                  value={editedName}
                  onChange={(e) => setEditedName(e.target.value)}
                  className={cn(inputClass, 'text-2xl font-bold font-heading py-1')}
                  autoFocus
                  onKeyDown={(e) => {
                    if (e.key === 'Enter') handleSaveName()
                    if (e.key === 'Escape') {
                      setEditedName(account?.name ?? '')
                      setIsEditingName(false)
                    }
                  }}
                />
                <Button onClick={handleSaveName} loading={isSavingName} size="icon-sm">
                  <Check className="h-4 w-4" />
                </Button>
                <Button
                  variant="secondary"
                  size="icon-sm"
                  onClick={() => {
                    setEditedName(account?.name ?? '')
                    setIsEditingName(false)
                  }}
                >
                  <X className="h-4 w-4" />
                </Button>
              </div>
            ) : (
              <>
                <h1 className="text-2xl font-bold font-heading text-foreground">{account?.name}</h1>
                {isAccountOwner && (
                  <button
                    onClick={() => setIsEditingName(true)}
                    className="text-muted-foreground transition-colors hover:text-foreground"
                    aria-label="Rename account"
                  >
                    <Pencil className="h-4 w-4" />
                  </button>
                )}
              </>
            )}
          </div>
          <div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-muted-foreground">
            <span className="inline-flex items-center gap-1.5">
              <Crown className="h-3.5 w-3.5" />
              {planLabel(plan)} plan
            </span>
            {sub && (
              <>
                <span aria-hidden>·</span>
                <span
                  className={cn(
                    sub.status === 'active' && 'text-success',
                    sub.status === 'trialing' && 'text-info',
                    sub.status === 'past_due' && 'text-warning',
                    sub.status === 'canceled' && 'text-danger'
                  )}
                >
                  {sub.status.charAt(0).toUpperCase() + sub.status.slice(1).replace('_', ' ')}
                </span>
              </>
            )}
            {ownerName && (
              <>
                <span aria-hidden>·</span>
                <span>Owned by {ownerName}</span>
              </>
            )}
            {memberCount !== undefined && (
              <>
                <span aria-hidden>·</span>
                <span>
                  {memberCount} {memberCount === 1 ? 'member' : 'members'}
                </span>
              </>
            )}
            <>
              <span aria-hidden>·</span>
              <span>Created {formatShortDate(account?.created_at)}</span>
            </>
          </div>
        </header>

        {/* ── Plan & Usage ───────────────────────────────────────────────── */}
        <section className="space-y-4 border-t border-border pt-8">
          <div className="flex items-baseline justify-between">
            <SectionLabel>Plan & usage</SectionLabel>
            <span className="text-xs text-muted-foreground">
              {sub?.current_period_end
                ? `Renews ${new Date(sub.current_period_end).toLocaleDateString()}`
                : 'No renewal scheduled'}
            </span>
          </div>

          {limits && usage ? (
            <div className="space-y-1">
              <UsageRow label="Flows" current={usage.tree_count} max={limits.max_trees} />
              <UsageRow
                label="Sessions / month"
                current={usage.session_count_this_month}
                max={limits.max_sessions_per_month}
              />
              {(() => {
                const seatCount = usage.user_count ?? (isAccountOwner ? members.length : null)
                return seatCount !== null ? (
                  <UsageRow label="Seats" current={seatCount} max={limits.max_users} />
                ) : null
              })()}
            </div>
          ) : (
            <p className="text-sm text-muted-foreground">Plan limits unavailable.</p>
          )}

          {plan !== 'enterprise' && (
            <div className="flex flex-wrap justify-end gap-2 pt-2">
              {plan === 'free' && <CheckoutButton plan="pro" />}
              <CheckoutButton plan="enterprise" />
            </div>
          )}
        </section>

        {/* ── People ─────────────────────────────────────────────────────── */}
        {isAccountOwner ? (
          <section className="space-y-5 border-t border-border pt-8">
            <SectionLabel>People</SectionLabel>

            <SeatCounterWidget />

            <form onSubmit={handleInvite} className="flex flex-wrap items-center gap-2">
              <input
                type="email"
                placeholder="teammate@company.com"
                value={inviteEmail}
                onChange={(e) => setInviteEmail(e.target.value)}
                required
                className={cn(inputClass, 'flex-1 min-w-[14rem]')}
              />
              <select
                value={inviteRole}
                onChange={(e) => setInviteRole(e.target.value)}
                aria-label="Invite role"
                className={inputClass}
              >
                <option value="engineer">Engineer</option>
                <option value="viewer">Viewer</option>
              </select>
              <Button type="submit" disabled={!inviteEmail.trim()} loading={isInviting}>
                {isInviting ? 'Sending…' : 'Invite'}
              </Button>
            </form>

            {(members.length > 0 || pendingInvites.length > 0) && (
              <ul className="divide-y divide-border">
                {members.map((member) => (
                  <li key={`member-${member.id}`} className="flex items-center gap-3 py-3">
                    <div className="min-w-0 flex-1">
                      <div className="flex items-center gap-2">
                        <span className="text-sm font-medium text-foreground truncate">
                          {member.name}
                        </span>
                        {!member.is_active && (
                          <span className="rounded-full bg-danger-dim px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-danger">
                            Inactive
                          </span>
                        )}
                      </div>
                      <div className="text-xs text-muted-foreground truncate">
                        {member.email}
                        {member.last_login && (
                          <span> · Last seen {formatShortDate(member.last_login)}</span>
                        )}
                      </div>
                    </div>
                    {member.account_role === 'owner' ? (
                      <span className="rounded-full bg-accent-dim px-2.5 py-0.5 text-xs font-medium text-accent-text">
                        Owner
                      </span>
                    ) : (
                      <select
                        value={member.account_role}
                        aria-label={`Role for ${member.name}`}
                        onChange={async (e) => {
                          try {
                            const updated = await accountsApi.updateMemberRole(
                              member.id,
                              e.target.value
                            )
                            setMembers((current) =>
                              current.map((entry) =>
                                entry.id === member.id
                                  ? { ...entry, account_role: updated.account_role }
                                  : entry
                              )
                            )
                            toast.success(`Role updated to ${updated.account_role}`)
                          } catch {
                            toast.error('Failed to update role')
                          }
                        }}
                        className={cn(
                          'rounded-md border border-border bg-card px-2 py-0.5 text-xs',
                          'text-foreground focus:border-primary/40 focus:outline-hidden'
                        )}
                      >
                        <option value="engineer">Engineer</option>
                        <option value="viewer">Viewer</option>
                      </select>
                    )}
                    {member.account_role !== 'owner' && (
                      <ConfirmButton
                        onConfirm={() => handleRemoveMember(member.id)}
                        confirmLabel="Remove?"
                        className="rounded p-1 text-muted-foreground hover:text-danger"
                        confirmClassName="rounded px-1.5 py-0.5 text-xs font-medium text-danger bg-danger-dim"
                        aria-label={`Remove ${member.name}`}
                      >
                        <X className="h-4 w-4" />
                      </ConfirmButton>
                    )}
                  </li>
                ))}

                {pendingInvites.map((invite) => (
                  <li key={`invite-${invite.id}`} className="flex items-center gap-3 py-3">
                    <Mail className="h-4 w-4 shrink-0 text-muted-foreground" />
                    <div className="min-w-0 flex-1">
                      <div className="text-sm font-medium text-foreground truncate">
                        {invite.email}
                      </div>
                      <div className="text-xs text-muted-foreground">
                        Pending
                        {invite.expires_at && (
                          <span>
                            {' '}
                            · Expires {new Date(invite.expires_at).toLocaleDateString()}
                          </span>
                        )}
                      </div>
                    </div>
                    <span className="rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground">
                      {invite.role}
                    </span>
                    <button
                      onClick={() => handleResendInvite(invite.id)}
                      disabled={resendingId === invite.id}
                      className="rounded p-1 text-muted-foreground transition-colors hover:text-foreground disabled:opacity-50"
                      aria-label={`Resend invite to ${invite.email}`}
                    >
                      {resendingId === invite.id ? (
                        <Loader2 className="h-4 w-4 animate-spin" />
                      ) : (
                        <RefreshCw className="h-4 w-4" />
                      )}
                    </button>
                  </li>
                ))}
              </ul>
            )}

            {account?.display_code && (
              <div className="flex flex-wrap items-center gap-2 text-xs text-muted-foreground">
                <span>Share to invite during signup:</span>
                <code className="rounded border border-border bg-code px-2 py-0.5 font-mono text-sm text-foreground">
                  {account.display_code}
                </code>
                <button
                  onClick={handleCopyDisplayCode}
                  className="rounded p-1 text-muted-foreground transition-colors hover:text-foreground"
                  aria-label="Copy display code"
                >
                  {copiedCode ? <Check className="h-3.5 w-3.5" /> : <Copy className="h-3.5 w-3.5" />}
                </button>
              </div>
            )}
          </section>
        ) : (
          <section className="border-t border-border pt-8">
            <SectionLabel>People</SectionLabel>
            <p className="mt-3 text-sm text-muted-foreground">
              Membership and invites are managed by the account owner
              {ownerName && <span> ({ownerName})</span>}. Contact your admin to make changes.
            </p>
          </section>
        )}

        {/* ── Settings ───────────────────────────────────────────────────── */}
        <section className="space-y-4 border-t border-border pt-8">
          <SectionLabel>Settings</SectionLabel>

          <div className="space-y-1">
            <SettingsRow
              to="/account/profile"
              icon={<UserCog className="h-4 w-4" />}
              title="Profile"
              description="Your name, email, and personal preferences"
            />
            <SettingsRow
              to="/account/billing"
              icon={<CreditCard className="h-4 w-4" />}
              title="Billing"
              description="Subscription, payment method, and invoices"
            />
          </div>

          {isAccountOwner && (
            <div className="space-y-1 border-t border-border pt-4">
              <SettingsRow
                to="/account/branding"
                icon={<Palette className="h-4 w-4" />}
                title="Branding"
                description="Logo, accent color, and company name"
                status={
                  limits?.custom_branding
                    ? { label: 'Included', tone: 'positive' }
                    : { label: 'Plan gated', tone: 'warning' }
                }
              />
              <SettingsRow
                to="/account/integrations"
                icon={<Plug className="h-4 w-4" />}
                title="Integrations"
                description="Connect PSA tools and external systems"
              />
              <SettingsRow
                to="/account/chat-retention"
                icon={<Clock className="h-4 w-4" />}
                title="Chat retention"
                description="Conversation retention and assistant data lifecycle"
              />
              <SettingsRow
                to="/account/security"
                icon={<Shield className="h-4 w-4" />}
                title="Session security"
                description="Session-expiration policy and active sessions"
              />
              <SettingsRow
                to="/account/categories"
                icon={<FolderTree className="h-4 w-4" />}
                title="Team categories"
                description="Shared flow categories for your workspace"
              />
              <SettingsRow
                to="/account/target-lists"
                icon={<Server className="h-4 w-4" />}
                title="Target lists"
                description="Saved server and device lists for the team"
              />
            </div>
          )}

          <div className="pt-2">
            <Link
              to="/feedback"
              className="inline-flex items-center gap-2 text-xs text-muted-foreground transition-colors hover:text-foreground"
            >
              <MessageSquareText className="h-3.5 w-3.5" />
              Need help? Send feedback or report a bug
            </Link>
          </div>
        </section>

        {/* ── Account actions (transfer / delete / leave) ────────────────── */}
        <section className="border-t border-border pt-8 space-y-3">
          {isAccountOwner ? (
            <>
              <div className="flex items-center justify-between gap-3">
                <div>
                  <p className="text-sm font-medium text-foreground">Transfer ownership</p>
                  <p className="text-xs text-muted-foreground">
                    Move ownership of this account to another member.
                  </p>
                </div>
                <Button variant="secondary" size="sm" onClick={() => setShowTransferModal(true)}>
                  Transfer
                </Button>
              </div>
              <div className="flex items-center justify-between gap-3">
                <div>
                  <p className="text-sm font-medium text-danger">Delete account</p>
                  <p className="text-xs text-muted-foreground">
                    Permanently delete the account and all data. Cannot be undone.
                  </p>
                </div>
                <Button variant="destructive" size="sm" onClick={() => setShowDeleteModal(true)}>
                  Delete
                </Button>
              </div>
            </>
          ) : (
            <div className="flex items-center justify-between gap-3">
              <div>
                <p className="text-sm font-medium text-danger">Leave account</p>
                <p className="text-xs text-muted-foreground">
                  Leave this account and create a personal one.
                </p>
              </div>
              <Button variant="destructive" size="sm" onClick={() => setShowLeaveModal(true)}>
                Leave
              </Button>
            </div>
          )}
        </section>

        {showTransferModal && (
          <TransferOwnershipModal
            members={members}
            onClose={() => setShowTransferModal(false)}
            onTransferred={() => {
              setShowTransferModal(false)
              loadData()
            }}
          />
        )}
        {showLeaveModal && account && (
          <LeaveAccountModal accountName={account.name} onClose={() => setShowLeaveModal(false)} />
        )}
        {showDeleteModal && <DeleteAccountModal onClose={() => setShowDeleteModal(false)} />}
      </div>
    </>
  )
}

export default AccountSettingsPage
