import React, { useEffect, useState } from 'react';

import {
  ArticlePublishingConfig,
  getArticlePublishing,
  saveArticlePublishing,
} from '../../service/articlePublishing/articlePublishing.service';
import Banner from '../widgets/Banner';
import Button from '../widgets/Button';
import ErrorWrapper from '../alert/ErrorWrapper';

/**
 * Sentinel select value meaning "publish as Pages under a parent path".
 */
const CUSTOM_VALUE: string = '__custom__';

/**
 * Settings section that lets the merchant choose where Recomaze publishes
 * AI-generated articles: an existing post type from a live dropdown, or a parent
 * "path" (e.g. guides) under which articles become child Pages at
 * /guides/article-name. It also picks the default categories the articles land
 * in, so large volumes stay organised instead of flooding /blog/.
 *
 * @return The article-publishing settings section.
 */
const ArticlePublishing = (): JSX.Element => {
  const [config, setConfig] = useState<ArticlePublishingConfig | null>(null);
  const [postType, setPostType] = useState<string>('');
  const [isCustom, setIsCustom] = useState<boolean>(false);
  // The parent page path used when publishing articles as child Pages.
  const [path, setPath] = useState<string>('');
  const [selectedTerms, setSelectedTerms] = useState<Record<string, number[]>>(
    {}
  );

  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [isSaving, setIsSaving] = useState<boolean>(false);
  const [saved, setSaved] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);

  const applyConfig = (data: ArticlePublishingConfig): void => {
    setConfig(data);
    // A configured parent path means "publish as child Pages under it".
    const usingPath: boolean = Boolean(data.parent_path);
    setIsCustom(usingPath);
    setPostType(usingPath ? CUSTOM_VALUE : data.post_type);
    setPath(data.parent_path || '');
    setSelectedTerms(data.selected_terms || {});
  };

  useEffect(() => {
    getArticlePublishing()
      .then(applyConfig)
      .catch((err: Error) =>
        setError(err?.message || 'Failed to load settings')
      )
      .finally(() => setIsLoading(false));
  }, []);

  useEffect(() => {
    if (error || saved) {
      const timerId: ReturnType<typeof setTimeout> = setTimeout(() => {
        setError(null);
        setSaved(false);
      }, 4000);
      return () => clearTimeout(timerId);
    }
    return undefined;
  }, [error, saved]);

  const handleSelectPostType = (value: string): void => {
    if (value === CUSTOM_VALUE) {
      setIsCustom(true);
      setPostType(CUSTOM_VALUE);
      return;
    }
    setIsCustom(false);
    setPostType(value);
    // Refresh the taxonomies (and their terms) for the newly chosen type.
    getArticlePublishing(value)
      .then(data => {
        setConfig(data);
        setSelectedTerms(data.selected_terms || {});
      })
      .catch((err: Error) =>
        setError(err?.message || 'Failed to load taxonomies')
      );
  };

  const toggleTerm = (taxonomy: string, termId: number): void => {
    setSelectedTerms(previous => {
      const current: number[] = previous[taxonomy] || [];
      const next: number[] = current.includes(termId)
        ? current.filter(id => id !== termId)
        : [...current, termId];
      return { ...previous, [taxonomy]: next };
    });
  };

  const handleSave = async (): Promise<void> => {
    if (isCustom && !path.trim()) {
      setError('Type a path (e.g. informatii) for the pages.');
      return;
    }
    try {
      setIsSaving(true);
      const response = await saveArticlePublishing(
        isCustom
          ? {
              post_type: 'page',
              parent_path: path.trim(),
              label: path.trim(),
              terms: selectedTerms,
            }
          : { post_type: postType, terms: selectedTerms }
      );
      const refreshed = await getArticlePublishing(response.post_type);
      applyConfig(refreshed);
      setSaved(true);
    } catch (err: any) {
      setError(err?.message || 'Could not save. Please try again.');
    } finally {
      setIsSaving(false);
    }
  };

  if (isLoading) {
    return (
      <div className="rounded-lg border border-gray-200 bg-white p-6 text-sm text-gray-500">
        Loading publishing settings...
      </div>
    );
  }

  return (
    <section className="space-y-6">
      <header>
        <h2 className="text-xl font-medium text-gray-900">
          Article Publishing
        </h2>
        <p className="mt-1 text-sm text-gray-500">
          Choose where Recomaze publishes AI-generated articles and which
          categories they go into. Keep your refined posts in /blog/ and send
          automated articles to their own post type.
        </p>
      </header>

      <Banner type="success" open={saved} setOpen={setSaved}>
        Publishing settings saved
      </Banner>

      <div className="rounded-lg border border-gray-200 bg-white p-6 space-y-6">
        <div>
          <label
            htmlFor="article-post-type"
            className="block text-sm font-medium text-gray-900 mb-2"
          >
            Publish into
          </label>
          <select
            id="article-post-type"
            value={postType}
            onChange={e => handleSelectPostType(e.target.value)}
            className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-gray-500 focus:outline-none"
          >
            {(config?.post_types || []).map(option => (
              <option key={option.slug} value={option.slug}>
                {option.label} ({option.slug})
              </option>
            ))}
            <option value={CUSTOM_VALUE}>Pages under a path…</option>
          </select>
        </div>

        {isCustom && (
          <div>
            <label
              htmlFor="article-path"
              className="block text-sm font-medium text-gray-900 mb-2"
            >
              Path
            </label>
            <input
              id="article-path"
              type="text"
              value={path}
              placeholder="guides"
              onChange={e => setPath(e.target.value)}
              className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-gray-500 focus:outline-none"
            />
            <p className="mt-2 text-sm text-gray-500">
              Articles become Pages under{' '}
              <code className="rounded bg-gray-100 px-1 py-0.5">
                /{(path || 'guides').replace(/^\/+|\/+$/g, '')}/article-name
              </code>
              . The parent page is created automatically.
            </p>
          </div>
        )}

        {!isCustom && (config?.taxonomies?.length || 0) > 0 && (
          <div className="space-y-4">
            <p className="text-sm font-medium text-gray-900">
              Default categories
            </p>
            {(config?.taxonomies || []).map(taxonomy => (
              <div key={taxonomy.slug}>
                <p className="text-sm text-gray-700 mb-2">{taxonomy.label}</p>
                {taxonomy.terms.length === 0 ? (
                  <p className="text-sm text-gray-400">
                    No {taxonomy.label.toLowerCase()} yet.
                  </p>
                ) : (
                  <div className="flex flex-wrap gap-2">
                    {taxonomy.terms.map(term => {
                      const checked: boolean = (
                        selectedTerms[taxonomy.slug] || []
                      ).includes(term.id);
                      return (
                        <label
                          key={term.id}
                          className={`cursor-pointer rounded-full border px-3 py-1 text-sm ${
                            checked
                              ? 'border-gray-900 bg-gray-900 text-white'
                              : 'border-gray-300 text-gray-700'
                          }`}
                        >
                          <input
                            type="checkbox"
                            className="sr-only"
                            checked={checked}
                            onChange={() => toggleTerm(taxonomy.slug, term.id)}
                          />
                          {term.name}
                        </label>
                      );
                    })}
                  </div>
                )}
              </div>
            ))}
          </div>
        )}

        <div className="flex items-center justify-between">
          <span className="text-sm text-gray-500">
            Current:{' '}
            <strong className="font-medium text-gray-900">
              {config?.post_type}
            </strong>
          </span>
          <Button
            type="button"
            isLoading={isSaving}
            disabled={isSaving}
            onClick={handleSave}
            className="whitespace-nowrap rounded-md bg-gray-900 px-5 py-2 text-sm font-medium text-white transition-colors hover:bg-gray-800 disabled:cursor-not-allowed disabled:opacity-50"
          >
            Save Changes
          </Button>
        </div>

        {error && (
          <div>
            <ErrorWrapper error={error} />
          </div>
        )}
      </div>
    </section>
  );
};

export default ArticlePublishing;
