import { useState, useMemo, useEffect } from 'react';
import {
  Avatar,
  Badge,
  Button,
  Input,
  MonoText,
  SectionHeader,
  Tag,
  Toggle,
  InlineEdit,
  ConfirmDialog,
  SplitPane,
  EntityList,
  Spinner,
  useToast,
} from '@cameleer/design-system';
import {
  useEnvironments,
  useCreateEnvironment,
  useUpdateEnvironment,
  useDeleteEnvironment,
  useUpdateDefaultContainerConfig,
} from '../../api/queries/admin/environments';
import type { Environment } from '../../api/queries/admin/environments';
import styles from './UserManagement.module.css';

export default function EnvironmentsPage() {
  const { toast } = useToast();
  const { data: environments = [], isLoading } = useEnvironments();

  const [search, setSearch] = useState('');
  const [selectedId, setSelectedId] = useState<string | null>(null);
  const [creating, setCreating] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Environment | null>(null);

  // Create form state
  const [newSlug, setNewSlug] = useState('');
  const [newDisplayName, setNewDisplayName] = useState('');
  const [newProduction, setNewProduction] = useState(false);

  // Mutations
  const createEnv = useCreateEnvironment();
  const updateEnv = useUpdateEnvironment();
  const deleteEnv = useDeleteEnvironment();
  const updateDefaults = useUpdateDefaultContainerConfig();

  const selected = useMemo(
    () => environments.find((e) => e.id === selectedId) ?? null,
    [environments, selectedId],
  );

  const filtered = useMemo(() => {
    if (!search) return environments;
    const q = search.toLowerCase();
    return environments.filter(
      (e) =>
        e.slug.toLowerCase().includes(q) ||
        e.displayName.toLowerCase().includes(q),
    );
  }, [environments, search]);

  const isDefault = selected?.slug === 'default';

  const duplicateSlug =
    newSlug.trim() !== '' &&
    environments.some((e) => e.slug.toLowerCase() === newSlug.trim().toLowerCase());

  async function handleCreate() {
    if (!newSlug.trim() || !newDisplayName.trim()) return;
    try {
      await createEnv.mutateAsync({
        slug: newSlug.trim(),
        displayName: newDisplayName.trim(),
        production: newProduction,
      });
      toast({ title: 'Environment created', description: newSlug.trim(), variant: 'success' });
      setCreating(false);
      setNewSlug('');
      setNewDisplayName('');
      setNewProduction(false);
    } catch {
      toast({ title: 'Failed to create environment', variant: 'error', duration: 86_400_000 });
    }
  }

  async function handleDelete() {
    if (!deleteTarget) return;
    try {
      await deleteEnv.mutateAsync(deleteTarget.id);
      toast({ title: 'Environment deleted', description: deleteTarget.slug, variant: 'warning' });
      if (selectedId === deleteTarget.id) setSelectedId(null);
      setDeleteTarget(null);
    } catch {
      toast({ title: 'Failed to delete environment', variant: 'error', duration: 86_400_000 });
      setDeleteTarget(null);
    }
  }

  async function handleRename(newName: string) {
    if (!selected) return;
    try {
      await updateEnv.mutateAsync({
        id: selected.id,
        displayName: newName,
        production: selected.production,
        enabled: selected.enabled,
      });
      toast({ title: 'Environment renamed', variant: 'success' });
    } catch {
      toast({ title: 'Failed to rename', variant: 'error', duration: 86_400_000 });
    }
  }

  async function handleToggleProduction(value: boolean) {
    if (!selected) return;
    try {
      await updateEnv.mutateAsync({
        id: selected.id,
        displayName: selected.displayName,
        production: value,
        enabled: selected.enabled,
      });
      toast({ title: value ? 'Marked as production' : 'Marked as non-production', variant: 'success' });
    } catch {
      toast({ title: 'Failed to update', variant: 'error', duration: 86_400_000 });
    }
  }

  async function handleToggleEnabled(value: boolean) {
    if (!selected) return;
    try {
      await updateEnv.mutateAsync({
        id: selected.id,
        displayName: selected.displayName,
        production: selected.production,
        enabled: value,
      });
      toast({ title: value ? 'Environment enabled' : 'Environment disabled', variant: 'success' });
    } catch {
      toast({ title: 'Failed to update', variant: 'error', duration: 86_400_000 });
    }
  }

  if (isLoading) return <Spinner size="md" />;

  return (
    <>
      <SplitPane
        list={
          <>
            {creating && (
              <div className={styles.createForm}>
                <Input
                  placeholder="Slug (e.g. staging) *"
                  value={newSlug}
                  onChange={(e) => setNewSlug(e.target.value)}
                />
                {duplicateSlug && (
                  <span className={styles.errorText}>Slug already exists</span>
                )}
                <Input
                  placeholder="Display name *"
                  value={newDisplayName}
                  onChange={(e) => setNewDisplayName(e.target.value)}
                />
                <label className={styles.securityRow}>
                  <Toggle checked={newProduction} onChange={() => setNewProduction(!newProduction)} />
                  Production environment
                </label>
                <div className={styles.createFormActions}>
                  <Button size="sm" variant="ghost" onClick={() => setCreating(false)}>
                    Cancel
                  </Button>
                  <Button
                    size="sm"
                    variant="primary"
                    onClick={handleCreate}
                    loading={createEnv.isPending}
                    disabled={!newSlug.trim() || !newDisplayName.trim() || duplicateSlug}
                  >
                    Create
                  </Button>
                </div>
              </div>
            )}

            <EntityList
              items={filtered}
              renderItem={(env) => (
                <>
                  <Avatar name={env.displayName} size="sm" />
                  <div className={styles.entityInfo}>
                    <div className={styles.entityName}>{env.displayName}</div>
                    <div className={styles.entityMeta}>
                      {env.slug}
                    </div>
                    <div className={styles.entityTags}>
                      {env.production && <Badge label="PROD" color="error" />}
                      {!env.production && <Badge label="NON-PROD" color="auto" />}
                      {!env.enabled && <Badge label="DISABLED" color="warning" />}
                    </div>
                  </div>
                </>
              )}
              getItemId={(env) => env.id}
              selectedId={selectedId ?? undefined}
              onSelect={setSelectedId}
              searchPlaceholder="Search environments..."
              onSearch={setSearch}
              addLabel="+ Add environment"
              onAdd={() => setCreating(true)}
              emptyMessage="No environments match your search"
            />
          </>
        }
        detail={
          selected ? (
            <>
              <div className={styles.detailHeader}>
                <Avatar name={selected.displayName} size="lg" />
                <div className={styles.detailHeaderInfo}>
                  <div className={styles.detailName}>
                    {isDefault ? (
                      selected.displayName
                    ) : (
                      <InlineEdit value={selected.displayName} onSave={handleRename} />
                    )}
                  </div>
                  <div className={styles.detailEmail}>
                    {selected.slug}
                    {isDefault && ' (built-in)'}
                  </div>
                </div>
                <Button
                  size="sm"
                  variant="danger"
                  onClick={() => setDeleteTarget(selected)}
                  disabled={isDefault}
                >
                  Delete
                </Button>
              </div>

              <div className={styles.metaGrid}>
                <span className={styles.metaLabel}>ID</span>
                <MonoText size="xs">{selected.id}</MonoText>
                <span className={styles.metaLabel}>Slug</span>
                <span className={styles.metaValue}>{selected.slug}</span>
                <span className={styles.metaLabel}>Created</span>
                <span className={styles.metaValue}>
                  {new Date(selected.createdAt).toLocaleDateString()}
                </span>
              </div>

              <SectionHeader>Configuration</SectionHeader>
              <div className={styles.securitySection}>
                <div className={styles.securityRow}>
                  <Toggle checked={selected.production} onChange={() => handleToggleProduction(!selected.production)} />
                  <span>Production environment</span>
                  {selected.production ? (
                    <Tag label="Dedicated resources" color="error" />
                  ) : (
                    <Tag label="Shared resources" color="auto" />
                  )}
                </div>
              </div>

              <SectionHeader>Status</SectionHeader>
              <div className={styles.securitySection}>
                <div className={styles.securityRow}>
                  <Toggle checked={selected.enabled} onChange={() => handleToggleEnabled(!selected.enabled)} />
                  <span>{selected.enabled ? 'Enabled' : 'Disabled'}</span>
                  {!selected.enabled && (
                    <Tag label="No new deployments" color="warning" />
                  )}
                </div>
                {!selected.enabled && (
                  <p className={styles.inheritedNote}>
                    Disabled environments do not allow new deployments. Active
                    deployments can only be started, stopped, or deleted.
                  </p>
                )}
              </div>

              <DefaultResourcesSection environment={selected} onSave={async (config) => {
                try {
                  await updateDefaults.mutateAsync({ id: selected.id, config });
                  toast({ title: 'Default resources updated', variant: 'success' });
                } catch {
                  toast({ title: 'Failed to update defaults', variant: 'error', duration: 86_400_000 });
                }
              }} saving={updateDefaults.isPending} />
            </>
          ) : null
        }
        emptyMessage="Select an environment to view details"
      />

      <ConfirmDialog
        open={deleteTarget !== null}
        onClose={() => setDeleteTarget(null)}
        onConfirm={handleDelete}
        message={`Delete environment "${deleteTarget?.displayName}"? All apps and deployments in this environment will be removed. This cannot be undone.`}
        confirmText={deleteTarget?.slug ?? ''}
        loading={deleteEnv.isPending}
      />
    </>
  );
}

// ── Default Resource Limits ─────────────────────────────────────────

function DefaultResourcesSection({ environment, onSave, saving }: {
  environment: Environment;
  onSave: (config: Record<string, unknown>) => Promise<void>;
  saving: boolean;
}) {
  const defaults = environment.defaultContainerConfig ?? {};
  const [editing, setEditing] = useState(false);
  const [memoryLimit, setMemoryLimit] = useState('');
  const [memoryReserve, setMemoryReserve] = useState('');
  const [cpuShares, setCpuShares] = useState('');
  const [cpuLimit, setCpuLimit] = useState('');

  useEffect(() => {
    setMemoryLimit(String(defaults.memoryLimitMb ?? ''));
    setMemoryReserve(String(defaults.memoryReserveMb ?? ''));
    setCpuShares(String(defaults.cpuShares ?? ''));
    setCpuLimit(String(defaults.cpuLimit ?? ''));
    setEditing(false);
  }, [environment.id]);

  function handleCancel() {
    setMemoryLimit(String(defaults.memoryLimitMb ?? ''));
    setMemoryReserve(String(defaults.memoryReserveMb ?? ''));
    setCpuShares(String(defaults.cpuShares ?? ''));
    setCpuLimit(String(defaults.cpuLimit ?? ''));
    setEditing(false);
  }

  async function handleSave() {
    await onSave({
      memoryLimitMb: memoryLimit ? parseInt(memoryLimit) : null,
      memoryReserveMb: memoryReserve ? parseInt(memoryReserve) : null,
      cpuShares: cpuShares ? parseInt(cpuShares) : null,
      cpuLimit: cpuLimit ? parseFloat(cpuLimit) : null,
    });
    setEditing(false);
  }

  return (
    <>
      <SectionHeader>Default Resource Limits</SectionHeader>
      <p className={styles.inheritedNote}>
        These defaults apply to new apps in this environment unless overridden per-app.
      </p>
      <div className={styles.metaGrid}>
        <span className={styles.metaLabel}>Memory Limit</span>
        {editing
          ? <Input value={memoryLimit} onChange={(e) => setMemoryLimit(e.target.value)} placeholder="e.g. 512" style={{ width: 100 }} />
          : <span className={styles.metaValue}>{defaults.memoryLimitMb ? `${defaults.memoryLimitMb} MB` : '—'}</span>}

        <span className={styles.metaLabel}>Memory Reserve</span>
        {editing
          ? <Input value={memoryReserve} onChange={(e) => setMemoryReserve(e.target.value)} placeholder="e.g. 256" style={{ width: 100 }} />
          : <span className={styles.metaValue}>{defaults.memoryReserveMb ? `${defaults.memoryReserveMb} MB` : '—'}</span>}

        <span className={styles.metaLabel}>CPU Shares</span>
        {editing
          ? <Input value={cpuShares} onChange={(e) => setCpuShares(e.target.value)} placeholder="e.g. 512" style={{ width: 100 }} />
          : <span className={styles.metaValue}>{String(defaults.cpuShares ?? '—')}</span>}

        <span className={styles.metaLabel}>CPU Limit</span>
        {editing
          ? <Input value={cpuLimit} onChange={(e) => setCpuLimit(e.target.value)} placeholder="e.g. 1.0" style={{ width: 100 }} />
          : <span className={styles.metaValue}>{defaults.cpuLimit ? `${defaults.cpuLimit} cores` : '—'}</span>}
      </div>
      <div style={{ marginTop: 8, display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
        {editing ? (
          <>
            <Button size="sm" variant="ghost" onClick={handleCancel}>Cancel</Button>
            <Button size="sm" variant="primary" onClick={handleSave} loading={saving}>Save</Button>
          </>
        ) : (
          <Button size="sm" variant="secondary" onClick={() => setEditing(true)}>Edit Defaults</Button>
        )}
      </div>
    </>
  );
}
