'use client';

/**
 * ConfigDrawer — per-module config editor, opened when an instance is selected.
 *
 * Uses the shared <Drawer> primitive (Radix Dialog-based side sheet).
 * The `inst` is resolved from `body[device]` by `selectedInstanceId`.
 * `isShared` is true when the same instanceId appears in BOTH device arrays.
 *
 * Wiring:
 *  - ConfigEditor onChange → state.updateConfig (updates both device arrays for shared instances)
 *  - Visibility toggles → state.updateVisibility (same invariant)
 *  - Unlink button → state.unlinkForDevice (assigns fresh instanceId to the current device only)
 *  - Delete button → AlertDialog → state.remove then state.select(null)
 *
 * All interactive elements are Radix primitives or <Button> components.
 * Token-only styling. RTL logical properties.
 */

import { useState, useEffect } from 'react';
import {
  Drawer,
  DrawerContent,
  DrawerHeader,
  DrawerTitle,
  DrawerFooter,
  DrawerClose,
} from '@/components/ui/overlays/Drawer';
import { Button } from '@/components/ui/primitives/Button';
import {
  AlertDialog,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogAction,
  AlertDialogCancel,
} from '@/components/ui/overlays/AlertDialog';
import { useOrganizer } from './state';
import { CLIENT_MODULE_REGISTRY } from '@/server/page-layout/client-registry';
import { useT } from '@/lib/i18n/react';
import { VisibilityToggles } from './VisibilityToggles';
import type { StringBundle } from '@/lib/i18n/types';
import type { ModuleVisibility } from '@/server/page-layout/types';
import {
  TooltipProvider,
  Tooltip,
  TooltipTrigger,
  TooltipContent,
} from '@/components/ui/overlays/Tooltip';
import { Icon } from '@/components/ui/icons/Icon';

export function ConfigDrawer() {
  const body = useOrganizer((s) => s.body);
  const device = useOrganizer((s) => s.device);
  const selectedInstanceId = useOrganizer((s) => s.selectedInstanceId);
  const select = useOrganizer((s) => s.select);
  const richTextEdit = useOrganizer((s) => s.richTextEdit);
  const updateConfig = useOrganizer((s) => s.updateConfig);
  const updateVisibility = useOrganizer((s) => s.updateVisibility);
  const remove = useOrganizer((s) => s.remove);
  const unlinkForDevice = useOrganizer((s) => s.unlinkForDevice);

  const t = useT('page_organizer');
  const tLabels = useT('module_labels');
  const tCommon = useT('common');

  // Snapshot config+visibility when drawer opens on a new instance — used by Cancel
  const [snapshot, setSnapshot] = useState<{
    instanceId: string;
    config: unknown;
    visibility: ModuleVisibility;
  } | null>(null);
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);

  // Resolve instance from the current device's array
  const inst = selectedInstanceId
    ? body[device].find((m) => m.instanceId === selectedInstanceId)
    : undefined;

  const def = inst ? CLIENT_MODULE_REGISTRY[inst.type] : undefined;

  // An instance is shared when the same instanceId appears in BOTH device arrays
  const isShared = inst
    ? body.mobile.some((m) => m.instanceId === inst.instanceId) &&
      body.desktop.some((m) => m.instanceId === inst.instanceId)
    : false;

  useEffect(() => {
    let cancelled = false;
    if (inst) {
      void Promise.resolve().then(() => {
        if (!cancelled) {
          setSnapshot({
            instanceId: inst.instanceId,
            config: inst.config,
            visibility: inst.visibility,
          });
        }
      });
    } else {
      void Promise.resolve().then(() => {
        if (!cancelled) setSnapshot(null);
      });
    }
    // Only re-snapshot when a different instance is opened, not on every config change

    return () => {
      cancelled = true;
    };
  }, [inst]);

  const isOpen = Boolean(inst && def) && richTextEdit === null;

  const handleSave = () => select(null);

  const handleCancel = () => {
    if (snapshot && inst && snapshot.instanceId === inst.instanceId) {
      updateConfig(inst.instanceId, snapshot.config);
      updateVisibility(inst.instanceId, snapshot.visibility);
    }
    select(null);
  };

  const handleOpenChange = (open: boolean) => {
    if (!open) select(null);
  };

  return (
    <Drawer open={isOpen} onOpenChange={handleOpenChange}>
      <DrawerContent side="end" data-config-drawer="true">
        {inst && def ? (
          <>
            <DrawerHeader>
              <DrawerClose aria-label={tCommon('close')} />
              <DrawerTitle>{tLabels(inst.type as keyof StringBundle['module_labels'])}</DrawerTitle>

              {/* Shared / this-device-only indicator + unlink action */}
              <div className="flex items-center justify-between gap-2 pt-1">
                <TooltipProvider delayDuration={200}>
                  <Tooltip>
                    <TooltipTrigger asChild>
                      <span className="text-text-muted inline-flex cursor-default items-center gap-1 text-sm">
                        {isShared ? t('shared_badge') : t('this_device_only_badge')}
                        <Icon name="Info" size="xs" color="muted" aria-hidden />
                      </span>
                    </TooltipTrigger>
                    <TooltipContent side="bottom" className="max-w-xs text-wrap">
                      {isShared ? t('help_shared_badge') : t('help_this_device_only_badge')}
                    </TooltipContent>
                  </Tooltip>
                </TooltipProvider>

                {isShared && (
                  <TooltipProvider delayDuration={200}>
                    <div className="flex items-center gap-1">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => unlinkForDevice(inst.instanceId, device)}
                      >
                        {t('unlink_device')}
                      </Button>
                      <Tooltip>
                        <TooltipTrigger asChild>
                          <Button
                            variant="ghost"
                            size="sm"
                            aria-label={tCommon('more_info')}
                            className="text-text-muted hover:text-text-secondary inline-flex items-center justify-center rounded-full p-1"
                          >
                            <Icon name="Info" size="xs" aria-hidden />
                          </Button>
                        </TooltipTrigger>
                        <TooltipContent side="bottom" className="max-w-xs text-wrap">
                          {t('help_unlink_device')}
                        </TooltipContent>
                      </Tooltip>
                    </div>
                  </TooltipProvider>
                )}
              </div>
            </DrawerHeader>

            {/* Config editor body */}
            <div className="flex flex-1 flex-col gap-6 overflow-y-auto px-6 py-4">
              {/* Visibility toggles */}
              <VisibilityToggles
                visibility={inst.visibility}
                onChange={(v) => updateVisibility(inst.instanceId, v)}
              />

              {/* Module-specific ConfigEditor */}
              <def.ConfigEditor
                instanceId={inst.instanceId}
                config={inst.config}
                onChange={(c) => updateConfig(inst.instanceId, c)}
              />
            </div>

            {/* Footer: save / cancel / delete */}
            <DrawerFooter>
              <div className="flex w-full items-center gap-2">
                <Button className="flex-1" onClick={handleSave}>
                  {t('btn_save')}
                </Button>
                <Button variant="secondary" className="flex-1" onClick={handleCancel}>
                  {t('btn_cancel')}
                </Button>
                <Button variant="danger" onClick={() => setDeleteConfirmOpen(true)}>
                  {t('btn_delete')}
                </Button>
              </div>
            </DrawerFooter>

            <AlertDialog open={deleteConfirmOpen} onOpenChange={setDeleteConfirmOpen}>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle>{t('btn_delete')}</AlertDialogTitle>
                  <AlertDialogDescription>{t('confirm_delete_module')}</AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel>{tCommon('cancel')}</AlertDialogCancel>
                  <AlertDialogAction
                    onClick={() => {
                      remove(device, inst.instanceId);
                      select(null);
                      setDeleteConfirmOpen(false);
                    }}
                  >
                    {t('btn_delete')}
                  </AlertDialogAction>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>
          </>
        ) : null}
      </DrawerContent>
    </Drawer>
  );
}
