import React, { useEffect, useRef, useState } from 'react';
import { createRoot } from 'react-dom/client';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { __ } from '@wordpress/i18n';
import { LocationWithRole } from '../../../types/location.entity';
import { App } from '../../../app';
import { LocationHeader } from '../location-header/location-header';
import { AuthFooter } from '../../auth/auth-footer/auth-footer';
import { Card } from '../../../shared/card/card';
import { CopyButton } from '../../../shared/copy-button/copy-button';
import { apiService } from '../../../services/api.service';

interface EmbedsProps {
  locationWithRole: LocationWithRole;
  bookingAppUrl: string;
}

interface ServiceCategory {
  id: number | string;
  name: string;
}

interface ServiceCategoriesPayload {
  serviceCategories?: ServiceCategory[];
}

function Embeds({ locationWithRole, bookingAppUrl }: EmbedsProps): JSX.Element {
  const bookingShortcode = `[ttsbs_btn_service_menu text="${__('Book now', 'timetailor-salon-booking')}"]`;
  const bookingShortcodeWithClass = `[ttsbs_btn_service_menu text="${__('Book now', 'timetailor-salon-booking')}" class="my-custom-button"]`;
  const serviceMenuShortcode = `[ttsbs_service_menu]`;
  const bookingButtonRef = useRef<HTMLButtonElement>(null);
  const bookingWithClassButtonRef = useRef<HTMLButtonElement>(null);
  const serviceMenuButtonRef = useRef<HTMLButtonElement>(null);
  const categoryButtonRef = useRef<HTMLButtonElement>(null);
  const [categories, setCategories] = useState<ServiceCategory[]>([]);
  const [selectedCategoryId, setSelectedCategoryId] = useState<string>('');

  const categoryShortcode = selectedCategoryId
    ? `[ttsbs_category_services category_id="${selectedCategoryId}"]`
    : __('Shortcode will appear after selecting a category', 'timetailor-salon-booking');

  const handleBookingCodeClick = (): void => {
    bookingButtonRef.current?.click();
  };

  const handleBookingWithClassCodeClick = (): void => {
    bookingWithClassButtonRef.current?.click();
  };

  const handleServiceMenuCodeClick = (): void => {
    serviceMenuButtonRef.current?.click();
  };

  const handleCategoryCodeClick = (): void => {
    if (!selectedCategoryId) {
      return;
    }

    categoryButtonRef.current?.click();
  };

  const extractServiceCategories = (payload: unknown): ServiceCategory[] => {
    if (!payload || typeof payload !== 'object' || !('categories' in payload)) {
      return [];
    }

    const categoriesPayload = (payload as { categories?: ServiceCategoriesPayload }).categories;

    if (!categoriesPayload || !Array.isArray(categoriesPayload.serviceCategories)) {
      return [];
    }

    return categoriesPayload.serviceCategories;
  };

  const fetchCategories = async (forceRefresh: boolean): Promise<void> => {
    try {
      const response = await apiService.getServiceCategories(forceRefresh);
      setCategories(extractServiceCategories(response));
    } catch (error) {
      setCategories([]);
    }
  };

  useEffect(() => {
    fetchCategories(false);
  }, []);

  const handleRefreshCategoriesClick = async () => {
    await fetchCategories(true);
    toast.success(__('Service menu updated.', 'timetailor-salon-booking'));
  };

  return (
    <div className="w-full max-w-3xl mx-auto flex flex-col gap-6">
      <Card title={__('Booking button', 'timetailor-salon-booking')}>
        <p>{__('Displays a button linking to your booking page.', 'timetailor-salon-booking')}</p>

        <div className="flex flex-col gap-3">
          <div className="font-medium">{__('Basic usage', 'timetailor-salon-booking')}</div>
          <div className="flex items-center gap-2">
            <code
              className="flex-1 block bg-gray-100 px-2 py-1.5 flex items-center rounded cursor-pointer hover:bg-gray-200 transition-colors"
              onClick={handleBookingCodeClick}
            >
              {bookingShortcode}
            </code>

            <CopyButton text={bookingShortcode} buttonRef={bookingButtonRef} />
          </div>
        </div>

        <div className="flex flex-col gap-3">
          <div className="font-medium">{__('Customizations', 'timetailor-salon-booking')}</div>
          <p>{__('Add CSS classes from your WordPress theme.', 'timetailor-salon-booking')}</p>
          <div className="flex items-center gap-2">
            <code
              className="flex-1 block bg-gray-100 px-2 py-1.5 flex items-center rounded cursor-pointer hover:bg-gray-200 transition-colors"
              onClick={handleBookingWithClassCodeClick}
            >
              {bookingShortcodeWithClass}
            </code>

            <CopyButton text={bookingShortcodeWithClass} buttonRef={bookingWithClassButtonRef} />
          </div>
        </div>
      </Card>

      <Card title={__('Service menu', 'timetailor-salon-booking')}>
        <p>{__('Displays the full service menu embed inside the page content.', 'timetailor-salon-booking')}</p>

        <div className="flex items-center gap-2">
          <code
            className="flex-1 block bg-gray-100 px-2 py-1.5 flex items-center rounded cursor-pointer hover:bg-gray-200 transition-colors"
            onClick={handleServiceMenuCodeClick}
          >
            {serviceMenuShortcode}
          </code>

          <CopyButton text={serviceMenuShortcode} buttonRef={serviceMenuButtonRef} />
        </div>
      </Card>

      <Card title={__('Categories', 'timetailor-salon-booking')}>
        <p>{__('Display services from a specific category. Select a category below to generate the shortcode.', 'timetailor-salon-booking')}</p>
        <select
          className="h-10 px-3 rounded border border-gray-300 bg-white"
          value={selectedCategoryId}
          onChange={(event) => setSelectedCategoryId(event.target.value)}
        >
          <option value="">{__('Select a category', 'timetailor-salon-booking')}</option>
          {categories.map((category) => (
            <option key={category.id} value={String(category.id)}>
              {category.name}
            </option>
          ))}
        </select>

        <div className="flex items-center gap-2">
          <code
            className="flex-1 block bg-gray-100 px-2 py-1.5 flex items-center rounded cursor-pointer hover:bg-gray-200 transition-colors"
            onClick={handleCategoryCodeClick}
          >
            {categoryShortcode}
          </code>

          {selectedCategoryId && <CopyButton text={categoryShortcode} buttonRef={categoryButtonRef} />}
        </div>
      </Card>

      <p>
        {__('Not seeing recent menu changes?', 'timetailor-salon-booking')}{' '}
        <button className="text-primary hover:underline" onClick={handleRefreshCategoriesClick}>
          {__('Refresh menu', 'timetailor-salon-booking')}
        </button>
      </p>

      <ToastContainer position="bottom-center" />
    </div>
  );
}

function initEmbeds(): void {
  const container = document.getElementById('ttsbs-embeds-root');
  if (!container) {
    return;
  }

  // init the app
  App.bootstrap({
    ajaxUrl: container.dataset.ajaxUrl || '',
    nonce: container.dataset.nonce || '',
    bookingAppUrl: container.dataset.bookingAppUrl || '',
  });

  const locationWithRole = JSON.parse(container.dataset.locationWithRole || '{}') as LocationWithRole;
  const bookingAppUrl = container.dataset.bookingAppUrl || '';

  const root = createRoot(container);
  root.render(
    <>
      <LocationHeader locationWithRole={locationWithRole} />
      <div className="flex-1">
        <Embeds locationWithRole={locationWithRole} bookingAppUrl={bookingAppUrl} />
      </div>
      <AuthFooter />
    </>
  );
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initEmbeds);
} else {
  initEmbeds();
}
