import { useCallback, useEffect, useState, type FormEvent } from "react"
import { Plus, RefreshCw, Trash2 } from "lucide-react"

import { useArcadiaClient } from "@crema/arcadia-core-client"
import { useToast } from "@crema/notification-ui"
import { ConfirmDialog, EmptyState } from "@crema/feedback-ui"

import { AppShell } from "~/components/layout/app-shell"
import { PageHeader } from "~/components/layout/page-header"
import { DataState, DialogError } from "~/components/data-state"
import { Button } from "~/components/ui/button"
import {
  Card,
  CardContent,
  CardHeader,
} from "~/components/ui/card"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "~/components/ui/dialog"
import { Input } from "~/components/ui/input"
import { Label } from "~/components/ui/label"
import { Switch } from "~/components/ui/switch"
import {
  createPlatformFlag,
  deletePlatformFlag,
  listPlatformFlags,
  updatePlatformFlag,
  type PlatformFlag,
} from "~/lib/arcadia/feature-flags"
import { errorMessage } from "~/lib/errors"
import { pageTitle } from "~/lib/page-meta"
import { useSession } from "~/lib/session"

export const meta = () => pageTitle("Feature flags")

export default function FeatureFlagsRoute() {
  const session = useSession()
  const arcadia = useArcadiaClient()
  const toast = useToast()

  const [flags, setFlags] = useState<PlatformFlag[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<unknown>(null)
  const [editorOpen, setEditorOpen] = useState(false)
  const [editing, setEditing] = useState<PlatformFlag | null>(null)
  const [pendingDelete, setPendingDelete] = useState<PlatformFlag | null>(null)
  const [busy, setBusy] = useState<string | null>(null)

  const refresh = useCallback(async () => {
    setError(null)
    setLoading(true)
    try {
      setFlags(await listPlatformFlags(arcadia))
    } catch (err) {
      setError(err)
    } finally {
      setLoading(false)
    }
  }, [arcadia])

  useEffect(() => {
    if (session) refresh()
  }, [session, refresh])

  const toggleDefault = async (flag: PlatformFlag, next: boolean) => {
    setBusy(flag.id)
    setFlags((prev) =>
      prev.map((f) => (f.id === flag.id ? { ...f, enabled_by_default: next } : f)),
    )
    try {
      await updatePlatformFlag(arcadia, flag.id, { enabled_by_default: next })
      toast.success(`${flag.key} defaults to ${next ? "on" : "off"}`)
    } catch (err) {
      setFlags((prev) => prev.map((f) => (f.id === flag.id ? flag : f)))
      toast.error(errorMessage(err, `update ${flag.key}`))
    } finally {
      setBusy(null)
    }
  }

  const remove = async () => {
    if (!pendingDelete) return
    const flag = pendingDelete
    try {
      await deletePlatformFlag(arcadia, flag.id)
      setPendingDelete(null)
      await refresh()
      toast.success(`Deleted flag ${flag.key}`)
    } catch (err) {
      setPendingDelete(null)
      toast.error(errorMessage(err, `delete ${flag.key}`))
    }
  }

  return (
    <AppShell>
      <PageHeader
        title="Feature flags"
        description="Platform-wide flags. Each defines a switch that every tenant inherits by default and can override from its own settings."
        actions={
          <>
            <Button
              variant="outline"
              size="sm"
              onClick={refresh}
              disabled={loading}
              data-action="feature-flags-refresh"
            >
              <RefreshCw className={`size-4 ${loading ? "animate-spin" : ""}`} />
              Refresh
            </Button>
            <Button
              size="sm"
              onClick={() => {
                setEditing(null)
                setEditorOpen(true)
              }}
              data-action="feature-flags-create"
            >
              <Plus className="size-4" />
              New flag
            </Button>
          </>
        }
      />

      <Card>
        <CardHeader className="text-xs text-muted-foreground">
          {flags.length} flag{flags.length === 1 ? "" : "s"}
        </CardHeader>
        <CardContent className="p-0">
          <DataState
            loading={loading}
            error={error}
            isEmpty={flags.length === 0}
            onRetry={refresh}
            loadingLabel="Loading feature flags…"
            empty={
              <EmptyState
                title="No feature flags yet"
                description="Create a flag to gate a feature across the platform. Tenants inherit its default and can override it per-tenant."
                className="py-12"
              />
            }
          >
            <ul className="divide-y">
              {flags.map((flag) => (
                <li key={flag.id} className="flex items-center gap-3 px-4 py-3">
                  <button
                    type="button"
                    className="min-w-0 flex-1 text-left"
                    onClick={() => {
                      setEditing(flag)
                      setEditorOpen(true)
                    }}
                    data-action={`feature-flag-${flag.key}-edit`}
                  >
                    <code className="font-mono text-sm">{flag.key}</code>
                    {flag.description ? (
                      <p className="mt-0.5 truncate text-xs text-muted-foreground">
                        {flag.description}
                      </p>
                    ) : null}
                  </button>

                  <div className="flex items-center gap-2 text-xs text-muted-foreground">
                    <span>Default</span>
                    <Switch
                      checked={flag.enabled_by_default}
                      onCheckedChange={(v) => toggleDefault(flag, v)}
                      disabled={busy === flag.id}
                      data-action={`feature-flag-${flag.key}-default`}
                      aria-label={`Default for ${flag.key}`}
                    />
                  </div>

                  <Button
                    variant="ghost"
                    size="icon-sm"
                    onClick={() => setPendingDelete(flag)}
                    aria-label={`Delete ${flag.key}`}
                    data-action={`feature-flag-${flag.key}-delete`}
                  >
                    <Trash2 className="size-4" />
                  </Button>
                </li>
              ))}
            </ul>
          </DataState>
        </CardContent>
      </Card>

      <FlagEditorDialog
        open={editorOpen}
        flag={editing}
        onClose={() => setEditorOpen(false)}
        onSaved={async (msg) => {
          setEditorOpen(false)
          await refresh()
          toast.success(msg)
        }}
      />

      <ConfirmDialog
        open={!!pendingDelete}
        onOpenChange={(o) => !o && setPendingDelete(null)}
        title="Delete feature flag?"
        description={
          pendingDelete
            ? `"${pendingDelete.key}" and every tenant's override of it are removed. Any code still reading this flag falls back to its built-in default.`
            : ""
        }
        confirmLabel="Delete"
        variant="danger"
        onConfirm={remove}
      />
    </AppShell>
  )
}

function FlagEditorDialog({
  open,
  flag,
  onClose,
  onSaved,
}: {
  open: boolean
  flag: PlatformFlag | null
  onClose: () => void
  onSaved: (message: string) => void
}) {
  const arcadia = useArcadiaClient()
  const isEdit = !!flag
  const [key, setKey] = useState("")
  const [description, setDescription] = useState("")
  const [enabledByDefault, setEnabledByDefault] = useState(false)
  const [submitting, setSubmitting] = useState(false)
  const [error, setError] = useState<unknown>(null)

  useEffect(() => {
    if (open) {
      setKey(flag?.key ?? "")
      setDescription(flag?.description ?? "")
      setEnabledByDefault(flag?.enabled_by_default ?? false)
      setError(null)
      setSubmitting(false)
    }
  }, [open, flag])

  const keyInvalid = key.length > 0 && !/^[a-z0-9_]+$/.test(key)
  const canSubmit = !submitting && key.trim().length > 0 && !keyInvalid

  async function handleSubmit(e: FormEvent) {
    e.preventDefault()
    if (!canSubmit) return
    setSubmitting(true)
    setError(null)
    try {
      if (isEdit) {
        await updatePlatformFlag(arcadia, flag!.id, {
          description: description.trim() || null,
          enabled_by_default: enabledByDefault,
        })
        onSaved(`Updated flag ${flag!.key}`)
      } else {
        await createPlatformFlag(arcadia, {
          key: key.trim(),
          description: description.trim() || null,
          enabled_by_default: enabledByDefault,
        })
        onSaved(`Created flag ${key.trim()}`)
      }
    } catch (err) {
      setError(err)
      setSubmitting(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="sm:max-w-md">
        <form onSubmit={handleSubmit}>
          <DialogHeader>
            <DialogTitle>{isEdit ? "Edit flag" : "New feature flag"}</DialogTitle>
            <DialogDescription>
              {isEdit
                ? "The key is fixed once created — code references it."
                : "The key is how code references this flag; it can't change later."}
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4 py-4">
            <div className="space-y-2">
              <Label htmlFor="flag-key">Key</Label>
              <Input
                id="flag-key"
                value={key}
                onChange={(e) => setKey(e.target.value)}
                placeholder="new_dashboard"
                autoFocus={!isEdit}
                disabled={isEdit}
                className="font-mono"
                data-action="feature-flag-form-key"
              />
              <p className="text-xs text-muted-foreground">
                {keyInvalid
                  ? "Lowercase letters, digits, and underscores only."
                  : "Lowercase letters, digits, and underscores."}
              </p>
            </div>

            <div className="space-y-2">
              <Label htmlFor="flag-description">Description</Label>
              <Input
                id="flag-description"
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder="What this flag controls"
                data-action="feature-flag-form-description"
              />
            </div>

            <div className="flex items-center justify-between rounded-md border px-3 py-2">
              <div>
                <div className="text-sm font-medium">Enabled by default</div>
                <div className="text-xs text-muted-foreground">
                  Tenants inherit this unless they override it.
                </div>
              </div>
              <Switch
                checked={enabledByDefault}
                onCheckedChange={setEnabledByDefault}
                data-action="feature-flag-form-default"
              />
            </div>
          </div>

          {error ? <DialogError error={error} context="save the flag" /> : null}

          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={onClose}
              disabled={submitting}
              data-action="feature-flag-form-cancel"
            >
              Cancel
            </Button>
            <Button type="submit" disabled={!canSubmit} data-action="feature-flag-form-save">
              {submitting ? "Saving…" : isEdit ? "Save" : "Create flag"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  )
}

export { RouteErrorBoundary as ErrorBoundary } from "~/components/route-error"
