import * as React from 'react';
import { createRoot } from 'react-dom/client';
import type { StrapiApp } from '@strapi/strapi/admin';
import { Button, DesignSystemProvider, Dialog, darkTheme, Box, Typography } from '@strapi/design-system';
import { WarningCircle } from '@strapi/icons';
import styled from 'styled-components';
import AuthLogo from './extensions/logo.png';
import MenuLogo from './extensions/logo.png';

const CONFIRM_MESSAGE =
  'Are you sure you want to delete this item? This action cannot be undone.';

// Path data for the @strapi/icons "Trash" icon. Lets us recognise a delete "trash"
// icon button regardless of the admin's display language.
const TRASH_ICON_PATH =
  'M27 6h-5V5a3 3 0 0 0-3-3h-6a3 3 0 0 0-3 3v1H5a1 1 0 0 0 0 2h1v18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h1a1 1 0 1 0 0-2M14 21a1 1 0 0 1-2 0v-8a1 1 0 0 1 2 0zm6 0a1 1 0 0 1-2 0v-8a1 1 0 0 1 2 0zm0-15h-8V5a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1z';

// Accessible names of destructive icon-only actions that delete instantly.
const DELETE_VERB_RE = /\b(delete|remove|reset|discard)\b/i;
// The edit-view header and list table-row "Delete entry" actions already open
// Strapi's own confirmation dialog — skip them so we don't double-confirm.
const ALREADY_CONFIRMED_RE = /^delete\s+entry\b/i;

// Marker set on a button while re-dispatching its click after confirmation so the
// capture-phase listener lets it through instead of prompting again.
const BYPASS_ATTR = 'dcConfirmed';

function normalizePath(value: string | null): string {
  return (value ?? '').replace(/\s+/g, ' ').trim();
}

const TRASH_PATH_NORMALIZED = normalizePath(TRASH_ICON_PATH);

function getAccessibleName(el: HTMLElement): string {
  return (el.getAttribute('aria-label') || el.getAttribute('title') || el.textContent || '').trim();
}

function isVisuallyHiddenText(node: Text, scope: HTMLElement): boolean {
  let el: Element | null = node.parentElement;
  while (el && el !== scope) {
    const cs = window.getComputedStyle(el);
    // Matches Strapi's VisuallyHidden (position: absolute; width: 1px; clipped).
    if (
      cs.position === 'absolute' &&
      (parseFloat(cs.width) <= 2 || cs.clip !== 'auto' || cs.clipPath !== 'none')
    ) {
      return true;
    }
    el = el.parentElement;
  }
  return false;
}

// An "icon-only" button renders just an icon; any label lives inside a visually
// hidden element. This excludes text delete buttons (e.g. the ones that already
// present their own confirmation) so we only intercept instant delete icons.
function isIconOnlyButton(btn: HTMLElement): boolean {
  if (!btn.querySelector('svg')) return false;
  const walker = document.createTreeWalker(btn, NodeFilter.SHOW_TEXT);
  let node = walker.nextNode();
  while (node) {
    if (node.nodeValue && node.nodeValue.trim() && !isVisuallyHiddenText(node as Text, btn)) {
      return false;
    }
    node = walker.nextNode();
  }
  return true;
}

function hasTrashIcon(btn: HTMLElement): boolean {
  const paths = btn.querySelectorAll('svg path');
  for (let i = 0; i < paths.length; i += 1) {
    if (normalizePath(paths[i].getAttribute('d')) === TRASH_PATH_NORMALIZED) return true;
  }
  return false;
}

function isDeleteCandidate(btn: HTMLElement): boolean {
  if (btn.hasAttribute('disabled') || btn.getAttribute('aria-disabled') === 'true') return false;
  if (!isIconOnlyButton(btn)) return false;
  const name = getAccessibleName(btn);
  if (ALREADY_CONFIRMED_RE.test(name)) return false;
  return hasTrashIcon(btn) || DELETE_VERB_RE.test(name);
}

const StyledWarning = styled(WarningCircle)`
  width: 24px;
  height: 24px;

  path {
    fill: ${({ theme }) => theme.colors.danger600};
  }
`;

// The dialog portals to <body>, whose text colour is the browser default (white
// in dark-mode OS settings, since Strapi's GlobalStyle only sets the body
// background). Typography defaults to `currentColor`, so force a light colour on
// the content to keep the header / message / icon visibly rendered in dark mode.
const ThemedDialogContent = styled(Dialog.Content)`
  color: #ffffff;
`;

let requestConfirm: (() => Promise<boolean>) | null = null;

function DeleteConfirmHost() {
  const [open, setOpen] = React.useState(false);
  const resolverRef = React.useRef<((value: boolean) => void) | null>(null);

  const openDialog = React.useCallback(() => {
    setOpen(true);
    return new Promise<boolean>((resolve) => {
      resolverRef.current = resolve;
    });
  }, []);

  const handleResult = React.useCallback((result: boolean) => {
    setOpen(false);
    const resolver = resolverRef.current;
    resolverRef.current = null;
    if (resolver) resolver(result);
  }, []);

  React.useLayoutEffect(() => {
    requestConfirm = openDialog;
    return () => {
      requestConfirm = null;
    };
  }, [openDialog]);

  return (
    <DesignSystemProvider theme={darkTheme} locale="en">
      <Dialog.Root
        open={open}
        onOpenChange={(nextOpen) => {
          if (!nextOpen) handleResult(false);
        }}
      >
        {open ? (
          <ThemedDialogContent>
            <Dialog.Header>Confirmation</Dialog.Header>
            <Dialog.Body icon={<StyledWarning />}>{CONFIRM_MESSAGE}</Dialog.Body>
            <Dialog.Footer>
              <Dialog.Cancel>
                <Button fullWidth variant="tertiary" onClick={() => handleResult(false)}>
                  Cancel
                </Button>
              </Dialog.Cancel>
              <Dialog.Action>
                <Button fullWidth variant="danger-light" onClick={() => handleResult(true)}>
                  Delete
                </Button>
              </Dialog.Action>
            </Dialog.Footer>
          </ThemedDialogContent>
        ) : null}
      </Dialog.Root>
    </DesignSystemProvider>
  );
}

function onCaptureClick(event: MouseEvent): void {
  const target = event.target;
  // Note: clicking the trash *icon* makes the target an SVG element (e.g. the
  // <path>), which is an Element but NOT an HTMLElement — so check for Element.
  if (!(target instanceof Element)) return;

  const btn = target.closest<HTMLButtonElement>('button, [role="button"]');
  if (!btn) return;

  if (btn.dataset[BYPASS_ATTR] === '1') {
    btn.dataset[BYPASS_ATTR] = '';
    return;
  }

  if (!isDeleteCandidate(btn)) return;
  if (!requestConfirm) return;

  event.preventDefault();
  event.stopPropagation();
  event.stopImmediatePropagation();

  void requestConfirm().then((confirmed) => {
    if (!confirmed) return;
    btn.dataset[BYPASS_ATTR] = '1';
    btn.click();
  });
}

let listenerInstalled = false;

function mountDeleteConfirmHost(): void {
  if (document.getElementById('strapi-delete-confirm')) return;
  const container = document.createElement('div');
  container.id = 'strapi-delete-confirm';
  document.body.appendChild(container);
  createRoot(container).render(<DeleteConfirmHost />);
}

function DashboardNotesHost() {
  const [isHome, setIsHome] = React.useState(false);
  const [isVisible, setIsVisible] = React.useState(true);

  React.useEffect(() => {
    const checkIsHome = () => {
      const path = window.location.pathname;
      setIsHome(path === '/admin' || path === '/admin/');
    };

    checkIsHome();

    // Observe body for changes to detect SPA route navigations
    const observer = new MutationObserver(() => {
      checkIsHome();
    });
    observer.observe(document.body, { childList: true, subtree: true });

    return () => observer.disconnect();
  }, []);

  if (!isHome || !isVisible) return null;

  return (
    <DesignSystemProvider theme={darkTheme} locale="en">
      <Box
        background="neutral0"
        hasRadius
        shadow="filterShadow"
        padding={6}
        style={{
          position: 'fixed',
          bottom: '32px',
          right: '32px',
          zIndex: 9999,
          width: '480px',
          border: '1px solid #dcdce4'
        }}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <Typography variant="alpha" textColor="neutral800" style={{ fontSize: '24px', fontWeight: 'bold' }}>
            Media Guidelines
          </Typography>
          <button
            onClick={() => setIsVisible(false)}
            style={{
              background: 'transparent',
              border: 'none',
              cursor: 'pointer',
              fontSize: '28px',
              lineHeight: '24px',
              color: '#666',
              padding: '0'
            }}
            aria-label="Close"
          >
            ×
          </button>
        </div>
        <Box paddingTop={4}>
          <Typography variant="epsilon" textColor="neutral700" style={{ lineHeight: '1.8', fontSize: '15px' }}>
            • <b>Image Size:</b> max 1mb<br />
            • <b>Image Formats:</b> JPG, JPEG, PNG, WebP, GIF, SVG<br />
            • <b>Image Ratio:</b> is provided in fields, please Refer that strictly<br />
            • <b>Aspect Ratio:</b> all field names contain the aspect ratio, for example bannerImage_3x1 means 3:1, please follow it strictly<br />
            • <b>Image Safe Area:</b> keep extra space on top, bottom, and sides so the main subject is not cut during auto resizing on different devices<br />
            • <b>Video Size:</b> max 10-15 mb<br />
            • <b>Video Formats:</b> MP4, MPEG, MPG, MOV, WebM<br />
            • <b>SAFL Mobile Hero Banner: </b> keep exactly like the <a href="https://mgmindia.s3.ap-south-1.amazonaws.com/uploads/Untitled_Card_Square_309443685c.png" target="_blank" rel="noopener noreferrer" style={{ color: '#4945ff', textDecoration: 'underline', fontWeight: 'bold' }}>reference image</a>
          </Typography>
        </Box>
      </Box>
    </DesignSystemProvider>
  );
}

function mountDashboardNotesHost(): void {
  if (document.getElementById('strapi-dashboard-notes')) return;
  const container = document.createElement('div');
  container.id = 'strapi-dashboard-notes';
  document.body.appendChild(container);
  createRoot(container).render(<DashboardNotesHost />);
}

export default {
  config: {
    auth: {
      logo: AuthLogo,
    },
    menu: {
      logo: MenuLogo,
    },
    translations: {
      en: {
        'Auth.form.welcome.title': 'Welcome to MGM India Dashboard',
        'Auth.form.welcome.subtitle': 'Login to your MGM Dashboard Account',
      },
    },
    locales: [
      // 'ar',
      // 'fr',
      // 'cs',
      // 'de',
      // 'da',
      // 'es',
      // 'he',
      // 'id',
      // 'it',
      // 'ja',
      // 'ko',
      // 'ms',
      // 'nl',
      // 'no',
      // 'pl',
      // 'pt-BR',
      // 'pt',
      // 'ru',
      // 'sk',
      // 'sv',
      // 'th',
      // 'tr',
      // 'uk',
      // 'vi',
      // 'zh-Hans',
      // 'zh',
    ],
  },
  bootstrap(app: StrapiApp) {
    mountDeleteConfirmHost();
    mountDashboardNotesHost();
    if (!listenerInstalled) {
      document.addEventListener('click', onCaptureClick, true);
      listenerInstalled = true;
    }
  },
};
