import type { ReactNode } from 'react'
import { Link, NavLink } from 'react-router-dom'
import type { AcAppKey } from '../lib/acAssets'
import { AcIcon } from './AcIcon'

const fieldClass =
  'ac-field w-full px-4 py-3 text-base text-ink outline-none transition placeholder:text-subtle focus:border-brand focus:ring-4 focus:ring-brand-soft'

export function PageTitle({ title, subtitle }: { title: string; subtitle?: string }) {
  return (
    <div className="mb-8">
      <div className="ac-title-bar">{title}</div>
      {subtitle ? (
        <p className="max-w-2xl text-lg leading-relaxed text-ink-secondary">{subtitle}</p>
      ) : null}
    </div>
  )
}

export function Card({ children, className = '' }: { children: ReactNode; className?: string }) {
  return (
    <div className={`ac-dialog rounded-[var(--radius-lg)] p-5 md:p-6 ${className}`}>{children}</div>
  )
}

export function Field({
  label,
  hint,
  children,
}: {
  label: string
  hint?: string
  children: ReactNode
}) {
  return (
    <label className="block text-base">
      <span className="mb-2 block font-bold text-ink">{label}</span>
      {hint ? <p className="ac-hint -mt-1 mb-2">{hint}</p> : null}
      {children}
    </label>
  )
}

export function Input(props: React.InputHTMLAttributes<HTMLInputElement>) {
  return <input {...props} className={`${fieldClass} ${props.className ?? ''}`} />
}

export function Textarea(
  props: React.TextareaHTMLAttributes<HTMLTextAreaElement> & { mono?: boolean },
) {
  const { mono, className, ...rest } = props
  return (
    <textarea
      {...rest}
      className={`${fieldClass} ${mono ? 'font-mono' : ''} ${className ?? ''}`}
    />
  )
}

export function Select(props: React.SelectHTMLAttributes<HTMLSelectElement>) {
  return <select {...props} className={`${fieldClass} ${props.className ?? ''}`} />
}

export function SectionTitle({ children }: { children: ReactNode }) {
  return <h2 className="ac-section-title">{children}</h2>
}

export function AcLink({
  to,
  children,
  className = '',
}: {
  to: string
  children: ReactNode
  className?: string
}) {
  return (
    <Link to={to} className={`ac-link ${className}`}>
      {children}
    </Link>
  )
}

export function TabLink({ to, children }: { to: string; children: ReactNode }) {
  return (
    <NavLink
      to={to}
      className={({ isActive }) => `ac-tab ${isActive ? 'ac-tab--active' : ''}`}
    >
      {children}
    </NavLink>
  )
}

export function ChoiceCard({
  active,
  title,
  hint,
  disabled,
  onClick,
}: {
  active?: boolean
  title: string
  hint?: string
  disabled?: boolean
  onClick: () => void
}) {
  return (
    <button
      type="button"
      disabled={disabled}
      onClick={onClick}
      className={`ac-choice-card ${active ? 'ac-choice-card--active' : ''}`}
    >
      <p className="text-base font-bold text-ink">{title}</p>
      {hint ? <p className="ac-hint mt-1">{hint}</p> : null}
    </button>
  )
}

export function SuccessText({ message }: { message?: string }) {
  if (!message) return null
  return <p className="ac-success-text">{message}</p>
}

export function Button({
  children,
  variant = 'primary',
  ...props
}: React.ButtonHTMLAttributes<HTMLButtonElement> & { variant?: 'primary' | 'ghost' | 'danger' | 'soft' }) {
  const styles =
    variant === 'primary'
      ? 'ac-btn-primary'
      : variant === 'danger'
        ? 'ac-btn-danger'
        : variant === 'soft'
          ? 'ac-btn-secondary bg-brand-soft text-brand'
          : 'ac-btn-secondary'
  const { className, ...rest } = props
  return (
    <button
      {...rest}
      className={`inline-flex min-h-11 items-center justify-center rounded-[var(--radius-pill)] px-5 py-2.5 text-base whitespace-nowrap transition disabled:opacity-50 ${styles} ${className ?? ''}`}
    >
      {children}
    </button>
  )
}

export function Badge({
  children,
  tone = 'neutral',
}: {
  children: ReactNode
  tone?: 'neutral' | 'brand' | 'sky' | 'success' | 'warning' | 'danger'
}) {
  const tones = {
    neutral: 'border-wood-dark bg-accent-soft text-ink',
    brand: 'border-brand bg-brand-soft text-brand',
    sky: 'border-accent bg-accent-soft text-accent',
    success: 'border-success bg-success-soft text-success',
    warning: 'border-warning bg-warning-soft text-warning',
    danger: 'border-danger bg-danger-soft text-danger',
  }
  return (
    <span
      className={`inline-flex items-center rounded-[var(--radius-pill)] border-2 px-3 py-1 text-sm font-bold ${tones[tone]}`}
    >
      {children}
    </span>
  )
}

export function ErrorText({ message }: { message?: string }) {
  if (!message) return null
  return <p className="mt-2 text-base font-bold text-danger">{message}</p>
}

export function Notice({
  tone = 'info',
  title,
  message,
}: {
  tone?: 'info' | 'success' | 'warning'
  title: string
  message?: string
}) {
  const tones = {
    info: 'border-accent bg-accent-soft text-ink',
    success: 'border-success/40 bg-success-soft text-ink',
    warning: 'border-warning/40 bg-warning-soft text-ink',
  }
  return (
    <div className={`rounded-[var(--radius-lg)] border-2 px-4 py-3 ${tones[tone]}`}>
      <p className="text-base font-bold">{title}</p>
      {message ? <p className="mt-1 text-base leading-relaxed text-ink-secondary">{message}</p> : null}
    </div>
  )
}

export function CopyableId({
  label,
  value,
  className = '',
}: {
  label: string
  value: string
  className?: string
}) {
  const copy = async () => {
    if (!value) return
    await navigator.clipboard.writeText(value)
  }
  return (
    <div className={`ac-slot px-5 py-5 ${className}`.trim()}>
      <div className="text-sm font-bold text-ink-secondary">{label}</div>
      <div className="mt-3 flex items-start justify-between gap-3">
        <code className="break-all text-base font-en text-ink">{value || '—'}</code>
        {value ? (
          <button type="button" onClick={copy} className="ac-btn-secondary shrink-0 px-3 py-1 text-sm">
            複製
          </button>
        ) : null}
      </div>
    </div>
  )
}

export function QuickLinkCard({
  to,
  title,
  desc,
  icon,
  className = '',
  guideBadge = false,
}: {
  to: string
  title: string
  desc: string
  icon: AcAppKey
  tag?: string
  className?: string
  guideBadge?: boolean
}) {
  return (
    <Link to={to} className={`ac-app-card group relative block p-5 ${className}`.trim()}>
      {guideBadge ? (
        <span className="hx-guide-badge" aria-hidden>
          完成連線
        </span>
      ) : null}
      <AcIcon app={icon} size="lg" className="mx-auto" />
      <h3 className="mt-3 text-center text-lg font-bold text-ink transition group-hover:text-brand">{title}</h3>
      <p className="mt-2 text-center text-base leading-relaxed text-ink-secondary">{desc}</p>
      <p className="mt-3 text-center text-base font-bold text-brand">打開 →</p>
    </Link>
  )
}

export function StatCard({
  label,
  value,
  hint,
  tone = 'default',
}: {
  label: string
  value: ReactNode
  hint?: string
  tone?: 'default' | 'brand' | 'sky'
}) {
  const slot =
    tone === 'brand' ? 'ac-slot ac-slot--brand' : tone === 'sky' ? 'ac-slot ac-slot--sky' : 'ac-slot'
  return (
    <div className={`${slot} p-5`}>
      <p className="text-base font-bold text-ink-secondary">{label}</p>
      <div className="mt-2 text-2xl font-black tracking-tight text-ink md:text-3xl">{value}</div>
      {hint ? <p className="mt-2 text-base text-muted">{hint}</p> : null}
    </div>
  )
}

export function TablePanel({
  title,
  count,
  children,
  className = '',
}: {
  title: string
  count?: number | string
  children: ReactNode
  className?: string
}) {
  return (
    <div className={`ac-table-panel ${className}`}>
      <div className="ac-table-panel__head">
        <span>{title}</span>
        {count !== undefined ? (
          <span>{typeof count === 'number' ? `共 ${count} 筆` : count}</span>
        ) : null}
      </div>
      {children}
    </div>
  )
}

export function TableShell({ children, className = '' }: { children: ReactNode; className?: string }) {
  return <div className={`ac-table-shell ${className}`}>{children}</div>
}

export function Table({
  children,
  className = '',
  minWidth,
}: {
  children: ReactNode
  className?: string
  minWidth?: string
}) {
  return (
    <table className={`ac-table ${className}`} style={minWidth ? { minWidth } : undefined}>
      {children}
    </table>
  )
}

export function TableEmpty({ children }: { children: ReactNode }) {
  return <p className="ac-table-empty">{children}</p>
}

export function TableAction({
  children,
  variant = 'default',
  className,
  ...props
}: React.ButtonHTMLAttributes<HTMLButtonElement> & {
  variant?: 'default' | 'danger' | 'link'
}) {
  const variantClass =
    variant === 'danger'
      ? 'ac-table-action--danger'
      : variant === 'link'
        ? 'ac-table-action--link'
        : ''
  return (
    <button type="button" {...props} className={`ac-table-action ${variantClass} ${className ?? ''}`}>
      {children}
    </button>
  )
}

export function StatusBadge({
  children,
  className = '',
}: {
  children: ReactNode
  className?: string
}) {
  return <span className={`ac-status-badge ${className}`}>{children}</span>
}

export function ProgressBar({ value, className = '' }: { value: number; className?: string }) {
  const pct = Math.min(100, Math.max(0, value))
  return (
    <div className={`ac-progress ${className}`}>
      <div className="ac-progress__fill" style={{ width: `${pct}%` }} />
    </div>
  )
}

export function HoverTip({
  label,
  children,
  placement = 'top',
  className = '',
}: {
  label: string
  children: ReactNode
  placement?: 'top' | 'bottom'
  className?: string
}) {
  return (
    <span className={`ac-hover-tip ac-hover-tip--${placement} ${className}`.trim()}>
      {children}
      <span className="ac-hover-tip__panel" role="tooltip">
        {label}
      </span>
    </span>
  )
}