'use client'

import { useId } from 'react'
import { AlertTriangle } from 'lucide-react'
import {
  validateIpRange,
  type IpAllowlistStatus,
  type SecretsStatus,
  type SecuritySourceMetadata,
} from '@actuate-media/cms-core/security-center'
import { SettingsSourceBadge, SettingsToggleRow } from './components.js'
import { SecurityCard, StatusRow } from './securityPrimitives.js'
import { parseAllowlistText, type SecurityForm } from './useSecuritySettings.js'

export function AccessProtectionCard({
  form,
  setField,
  canEdit,
  ipAllowlist,
  secrets,
  csrfEnabled,
  uploadValidation,
  sources,
  onNavigate,
}: {
  form: SecurityForm
  setField: <K extends keyof SecurityForm>(key: K, value: SecurityForm[K]) => void
  canEdit: boolean
  ipAllowlist: IpAllowlistStatus
  secrets: SecretsStatus
  csrfEnabled: boolean
  uploadValidation: boolean
  sources: Record<string, SecuritySourceMetadata>
  onNavigate?: (path: string) => void
}) {
  const headingId = useId()
  const allowlistId = useId()
  const allowlistHintId = useId()

  const entries = parseAllowlistText(form.ipAllowlistText)
  const invalidEntries = entries.filter((entry) => !validateIpRange(entry))
  const configRanges = ipAllowlist.configRanges ?? []

  const distributed = secrets.rateLimitBackend === 'distributed'

  return (
    <SecurityCard
      headingId={headingId}
      title="Access Control"
      description="Restrict where the admin and CMS API can be reached from, and control the audit trail."
    >
      {/* ── Allowed IP addresses ─────────────────────────────────────────── */}
      <div className="space-y-2">
        <div className="flex items-center justify-between gap-2">
          <label htmlFor={allowlistId} className="text-foreground text-base font-medium">
            Allowed IP addresses
          </label>
          <SettingsSourceBadge meta={sources.ipAllowlist} />
        </div>
        <textarea
          id={allowlistId}
          rows={3}
          value={form.ipAllowlistText}
          disabled={!canEdit}
          onChange={(e) => setField('ipAllowlistText', e.target.value)}
          placeholder={'203.0.113.0/24\n198.51.100.42'}
          aria-describedby={allowlistHintId}
          aria-invalid={invalidEntries.length > 0 || undefined}
          className="border-border bg-input-background text-foreground focus-visible:ring-ring w-full resize-y rounded-md border px-3 py-2 font-mono text-sm focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50"
        />
        <p id={allowlistHintId} className="text-muted-foreground text-sm">
          Restrict admin access to these ranges. One IP or CIDR range per line; leave empty to allow
          all addresses.
        </p>
        {invalidEntries.length > 0 && (
          <p className="text-destructive text-sm" role="alert">
            Invalid entries: {invalidEntries.join(', ')}
          </p>
        )}
        {entries.length > 0 && (
          <div className="border-warning/30 bg-warning/10 text-warning flex items-start gap-2 rounded-md border p-2.5 text-sm">
            <AlertTriangle size={15} className="mt-0.5 shrink-0" aria-hidden="true" />
            <span>
              Make sure your own IP
              {ipAllowlist.currentIp ? (
                <>
                  {' '}
                  (<span className="font-mono">{ipAllowlist.currentIp}</span>)
                </>
              ) : null}{' '}
              is covered — saving a list that excludes it will lock you out of the admin.
            </span>
          </div>
        )}
        {configRanges.length > 0 && (
          <div className="pt-1">
            <p className="text-muted-foreground text-sm">
              Always enforced from <code className="font-mono">admin.ipAllowlist</code> in
              actuate.config.ts:
            </p>
            <div className="text-muted-foreground mt-1 flex flex-wrap gap-1.5">
              {configRanges.map((r) => (
                <code key={r} className="bg-muted rounded px-1.5 py-0.5 font-mono text-xs">
                  {r}
                </code>
              ))}
            </div>
          </div>
        )}
        {ipAllowlist.currentIp && ipAllowlist.enabled && (
          <StatusRow
            status={
              ipAllowlist.currentIpAllowed === null
                ? 'unknown'
                : ipAllowlist.currentIpAllowed
                  ? 'pass'
                  : 'fail'
            }
            label="Your current IP"
            value={
              <span className="font-mono text-xs">
                {ipAllowlist.currentIp}
                {ipAllowlist.currentIpAllowed === false && ' (blocked)'}
              </span>
            }
          />
        )}
      </div>

      {/* ── Audit logging ────────────────────────────────────────────────── */}
      <div className="border-border mt-4 border-t pt-4">
        <SettingsToggleRow
          label="Audit logging"
          description="Record every content change, login and settings update. Security-critical events (failed logins, MFA and security policy changes) are always recorded."
          checked={form.auditLoggingEnabled}
          disabled={!canEdit}
          onChange={(value) => setField('auditLoggingEnabled', value)}
        />
      </div>

      {/* ── Request protection ──────────────────────────────────────────── */}
      <div className="border-border mt-4 space-y-2 border-t pt-4">
        <StatusRow
          status={csrfEnabled ? 'pass' : 'fail'}
          label="CSRF protection"
          value={csrfEnabled ? 'Enabled' : 'Disabled'}
          badge={<SettingsSourceBadge meta={sources.csrf} />}
        />
        <StatusRow
          status={distributed ? 'pass' : 'warning'}
          label="Rate limiting"
          value={distributed ? 'Distributed (Upstash)' : 'In-memory'}
          badge={<SettingsSourceBadge meta={sources.rateLimiting} />}
        />
        <StatusRow
          status={uploadValidation ? 'pass' : 'warning'}
          label="Upload validation"
          value="MIME + magic bytes + SVG sanitization"
          badge={<SettingsSourceBadge meta={sources.uploadValidation} />}
        />
        {onNavigate && (
          <button
            type="button"
            onClick={() => onNavigate('/media')}
            className="text-brand mt-1 text-sm hover:underline"
          >
            Manage upload rules in Media →
          </button>
        )}
      </div>
    </SecurityCard>
  )
}
