'use client';

import { AnimatePresence, motion } from 'framer-motion';
import { Bell, Loader2, Sparkles, X } from 'lucide-react';
import { signOutToPath } from '@/lib/auth-client';
import { useCallback, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import TemplateSelector from '@/app/components/TemplateSelector';
import UTMBuilder from '@/app/components/UTMBuilder';
import OGEditor from '@/app/components/OGEditor';
import ApiErrorAlert from '@/app/components/ApiErrorAlert';
import { useToast } from '@/app/components/ToastProvider';
import { getResponseErrorTextWithRequestId } from '@/lib/api-client';
import { config } from '@/lib/config';
import { datetimeLocalToIso } from '@/lib/datetime-local';
import { getRuntimeClientConfig } from '@/lib/runtime-client-config';
import type { PlanFeatures } from '@/lib/plans/types';

type UTMParams = {
  utmSource: string;
  utmMedium: string;
  utmCampaign: string;
  utmTerm: string;
  utmContent: string;
};

type CreateLinkDialogProps = {
  isOpen: boolean;
  onClose: () => void;
  onCreated: () => Promise<void> | void;
  planFeatures: PlanFeatures;
  initialFolderId?: string | null;
};

type TelegramClickNotificationsStatus = {
  hasBotToken: boolean;
  featureAvailableByPlan: boolean;
  canSendToUserNow: boolean;
};

const EMPTY_UTM: UTMParams = {
  utmSource: '',
  utmMedium: '',
  utmCampaign: '',
  utmTerm: '',
  utmContent: '',
};

const EMPTY_OG = {
  ogTitle: '',
  ogDescription: '',
  ogImage: '',
};

const EMPTY_TELEGRAM_CLICK_STATUS: TelegramClickNotificationsStatus = {
  hasBotToken: false,
  featureAvailableByPlan: false,
  canSendToUserNow: false,
};

function isUnauthorizedResponse(response: Response) {
  return response.status === 401;
}

function hasAdvancedAccess(features: PlanFeatures) {
  return features.customSlug || features.password || features.expiresAt || features.clickLimit || features.manualOgEditing;
}

export default function CreateLinkDialog({
  isOpen,
  onClose,
  onCreated,
  planFeatures,
  initialFolderId,
}: CreateLinkDialogProps) {
  const toast = useToast();
  const runtimeConfig = getRuntimeClientConfig();

  const [longUrl, setLongUrl] = useState('');
  const [title, setTitle] = useState('');
  const [description, setDescription] = useState('');
  const [customSlug, setCustomSlug] = useState('');
  const [expiresAtInput, setExpiresAtInput] = useState('');
  const [clickLimitInput, setClickLimitInput] = useState('');
  const [passwordInput, setPasswordInput] = useState('');
  const [showAdvanced, setShowAdvanced] = useState(false);
  const [telegramClickNotificationsEnabled, setTelegramClickNotificationsEnabled] = useState(false);
  const [telegramClickStatus, setTelegramClickStatus] = useState<TelegramClickNotificationsStatus>({
    ...EMPTY_TELEGRAM_CLICK_STATUS,
    featureAvailableByPlan: planFeatures.telegramClickNotifications,
  });
  const [isTelegramStatusLoading, setIsTelegramStatusLoading] = useState(false);

  const [utmParams, setUtmParams] = useState<UTMParams>(EMPTY_UTM);
  const [isUtmOpen, setIsUtmOpen] = useState(false);
  const [templatesRefreshToken, setTemplatesRefreshToken] = useState(0);

  const [ogEditorData, setOgEditorData] = useState(EMPTY_OG);
  const [ogMode, setOgMode] = useState<'source' | 'custom'>('source');
  const [isOgUploading, setIsOgUploading] = useState(false);

  const [isCreating, setIsCreating] = useState(false);
  const [isSuccess, setIsSuccess] = useState(false);
  const [formError, setFormError] = useState('');

  const shortUrlPreview = `${runtimeConfig.domain || config.domain}/${customSlug || '...'}`;

  const projectTimeZone = runtimeConfig.timeZone;

  const resetForm = useCallback(() => {
    setLongUrl('');
    setTitle('');
    setDescription('');
    setCustomSlug('');
    setExpiresAtInput('');
    setClickLimitInput('');
    setPasswordInput('');
    setShowAdvanced(false);
    setTelegramClickNotificationsEnabled(false);
    setTelegramClickStatus({
      ...EMPTY_TELEGRAM_CLICK_STATUS,
      featureAvailableByPlan: planFeatures.telegramClickNotifications,
    });
    setIsTelegramStatusLoading(false);
    setUtmParams(EMPTY_UTM);
    setIsUtmOpen(false);
    setTemplatesRefreshToken(0);
    setOgEditorData(EMPTY_OG);
    setOgMode('source');
    setIsOgUploading(false);
    setIsCreating(false);
    setIsSuccess(false);
    setFormError('');
  }, [planFeatures.telegramClickNotifications]);

  useEffect(() => {
    if (isOpen) {
      resetForm();
    }
  }, [isOpen, resetForm]);

  useEffect(() => {
    if (!planFeatures.manualOgEditing) {
      setOgMode('source');
      setOgEditorData(EMPTY_OG);
    }
  }, [planFeatures.manualOgEditing]);

  useEffect(() => {
    if (!isOpen) {
      return;
    }

    let isCancelled = false;

    const loadTelegramStatus = async () => {
      setIsTelegramStatusLoading(true);

      try {
        const response = await fetch('/api/profile/telegram', { cache: 'no-store' });

        if (!response.ok) {
          if (!isCancelled) {
            setTelegramClickStatus({
              ...EMPTY_TELEGRAM_CLICK_STATUS,
              featureAvailableByPlan: planFeatures.telegramClickNotifications,
            });
          }
          return;
        }

        const data = await response.json() as {
          clickNotifications?: Partial<TelegramClickNotificationsStatus>;
        };

        if (isCancelled) {
          return;
        }

        setTelegramClickStatus({
          hasBotToken: Boolean(data.clickNotifications?.hasBotToken),
          featureAvailableByPlan: Boolean(data.clickNotifications?.featureAvailableByPlan),
          canSendToUserNow: Boolean(data.clickNotifications?.canSendToUserNow),
        });
      } catch {
        if (!isCancelled) {
          setTelegramClickStatus({
            ...EMPTY_TELEGRAM_CLICK_STATUS,
            featureAvailableByPlan: planFeatures.telegramClickNotifications,
          });
        }
      } finally {
        if (!isCancelled) {
          setIsTelegramStatusLoading(false);
        }
      }
    };

    void loadTelegramStatus();

    return () => {
      isCancelled = true;
    };
  }, [isOpen, planFeatures.telegramClickNotifications]);

  const handleToggleTelegramNotifications = useCallback((nextValue: boolean) => {
    if (!nextValue) {
      setTelegramClickNotificationsEnabled(false);
      setFormError('');
      return;
    }

    if (!telegramClickStatus.featureAvailableByPlan) {
      setFormError('Telegram-уведомления о кликах доступны на тарифе Lite и выше.');
      return;
    }

    if (isTelegramStatusLoading) {
      setFormError('Проверяем настройки Telegram. Попробуйте ещё раз через пару секунд.');
      return;
    }

    if (!telegramClickStatus.hasBotToken) {
      setFormError('Токен Telegram-бота не настроен. Добавьте его в настройках профиля.');
      return;
    }

    setFormError('');
    setTelegramClickNotificationsEnabled(true);
  }, [isTelegramStatusLoading, telegramClickStatus.featureAvailableByPlan, telegramClickStatus.hasBotToken]);

  const handleApplyTemplate = useCallback((template: {
    utmSource?: string;
    utmMedium?: string;
    utmCampaign?: string;
    utmTerm?: string;
    utmContent?: string;
  }) => {
    setUtmParams({
      utmSource: template.utmSource || '',
      utmMedium: template.utmMedium || '',
      utmCampaign: template.utmCampaign || '',
      utmTerm: template.utmTerm || '',
      utmContent: template.utmContent || '',
    });
    setIsUtmOpen(true);
  }, []);

  const handleSaveTemplate = useCallback(async (templateData: UTMParams & { name: string }) => {
    try {
      const response = await fetch('/api/templates', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: templateData.name,
          utmSource: templateData.utmSource,
          utmMedium: templateData.utmMedium,
          utmCampaign: templateData.utmCampaign,
          utmTerm: templateData.utmTerm,
          utmContent: templateData.utmContent,
        }),
      });

      if (!response.ok) {
        if (isUnauthorizedResponse(response)) {
          await signOutToPath('/login');
          return;
        }
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось сохранить шаблон'));
      }

      toast.success('UTM шаблон сохранен');
      setTemplatesRefreshToken((prev) => prev + 1);
    } catch (error) {
      toast.error(error instanceof Error ? error.message : 'Не удалось сохранить шаблон');
    }
  }, [toast]);

  const handleSubmit = useCallback(async (event: React.FormEvent) => {
    event.preventDefault();
    if (isCreating || isOgUploading) return;

    const rawLongUrl = longUrl.trim();
    if (!rawLongUrl) {
      setFormError('Введите длинную ссылку');
      return;
    }

    setIsCreating(true);
    setFormError('');

    try {
      const hasScheme = /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(rawLongUrl);
      const normalizedLongUrl = hasScheme ? rawLongUrl : `https://${rawLongUrl}`;
      const parsed = new URL(normalizedLongUrl);

      if (utmParams.utmSource) parsed.searchParams.set('utm_source', utmParams.utmSource);
      if (utmParams.utmMedium) parsed.searchParams.set('utm_medium', utmParams.utmMedium);
      if (utmParams.utmCampaign) parsed.searchParams.set('utm_campaign', utmParams.utmCampaign);
      if (utmParams.utmTerm) parsed.searchParams.set('utm_term', utmParams.utmTerm);
      if (utmParams.utmContent) parsed.searchParams.set('utm_content', utmParams.utmContent);

      const payload: Record<string, unknown> = {
        longUrl: parsed.toString(),
        title: title.trim() || null,
        description: description.trim() || null,
        folderId: initialFolderId || null,
        tagIds: [],
        telegramClickNotificationsEnabled,
      };

      if (planFeatures.customSlug) payload.customSlug = customSlug.trim() || null;
      if (planFeatures.expiresAt) payload.expiresAt = datetimeLocalToIso(expiresAtInput, projectTimeZone);
      if (planFeatures.clickLimit) payload.clickLimit = clickLimitInput ? Number(clickLimitInput) : null;
      if (planFeatures.password) payload.password = passwordInput || null;
      if (planFeatures.manualOgEditing && ogMode === 'custom') {
        payload.ogTitle = ogEditorData.ogTitle || null;
        payload.ogDescription = ogEditorData.ogDescription || null;
        payload.ogImage = ogEditorData.ogImage || null;
      }

      const response = await fetch('/api/links', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        if (isUnauthorizedResponse(response)) {
          await signOutToPath('/login');
          return;
        }
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Не удалось создать ссылку'));
      }

      setIsSuccess(true);
      toast.success('Ссылка успешно создана');
      window.setTimeout(() => {
        onClose();
      }, 420);
      void Promise.resolve(onCreated()).catch(() => {
        // ignore background refresh errors
      });
    } catch (error) {
      setFormError(error instanceof Error ? error.message : 'Не удалось создать ссылку');
    } finally {
      setIsCreating(false);
    }
  }, [
    clickLimitInput,
    customSlug,
    description,
    expiresAtInput,
    isCreating,
    isOgUploading,
    longUrl,
    ogEditorData.ogDescription,
    ogEditorData.ogImage,
    ogEditorData.ogTitle,
    ogMode,
    onClose,
    onCreated,
    passwordInput,
    planFeatures.clickLimit,
    planFeatures.customSlug,
    planFeatures.expiresAt,
    planFeatures.manualOgEditing,
    planFeatures.password,
    initialFolderId,
    telegramClickNotificationsEnabled,
    projectTimeZone,
    title,
    toast,
    utmParams.utmCampaign,
    utmParams.utmContent,
    utmParams.utmMedium,
    utmParams.utmSource,
    utmParams.utmTerm,
  ]);

  if (!isOpen) return null;

  const dialogContent = (
    <AnimatePresence>
      <motion.div
        className="fixed inset-0 z-[90] flex items-center justify-center p-4"
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
      >
        <motion.button
          type="button"
          aria-label="Закрыть окно создания"
          onClick={onClose}
          className="absolute inset-0 bg-black/70 backdrop-blur-sm"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          exit={{ opacity: 0 }}
        />
        <motion.div
          initial={{ opacity: 0, y: 20, scale: 0.98 }}
          animate={{ opacity: 1, y: 0, scale: 1 }}
          exit={{ opacity: 0, y: 12, scale: 0.98 }}
          transition={{ duration: 0.2 }}
          className="relative w-full max-w-3xl max-h-[90vh] overflow-y-auto rounded-2xl border border-white/10 bg-[#0A0A0A]/95 backdrop-blur-xl shadow-[0_0_32px_rgba(139,92,246,0.1)]"
        >
          <div className="sticky top-0 z-10 px-5 py-4 border-b border-white/10 bg-[#0A0A0A]/95 backdrop-blur-xl flex items-center justify-between">
            <div className="min-w-0">
              <h3 className="text-lg font-semibold text-white">Создать ссылку</h3>
            </div>
            <button
              type="button"
              onClick={onClose}
              className="w-9 h-9 rounded-xl border border-white/10 bg-white/[0.03] text-gray-400 hover:text-white hover:bg-white/[0.08] transition-colors inline-flex items-center justify-center"
              aria-label="Закрыть"
            >
              <X className="w-4 h-4" />
            </button>
          </div>

          <form onSubmit={handleSubmit} className="p-5 space-y-4">
            <div className="rounded-xl border border-white/10 bg-white/[0.02] p-4">
              <p className="text-sm text-gray-300 mb-3 flex items-center gap-2">
                <Sparkles className="w-4 h-4 text-violet-300" />
                Базовые поля
              </p>
              <div className="grid grid-cols-1 gap-3">
                <div>
                  <label className="block text-xs text-gray-400 mb-1.5">Длинная ссылка *</label>
                  <input
                    value={longUrl}
                    onChange={(event) => setLongUrl(event.target.value)}
                    placeholder="example.com/path или https://example.com/path"
                    className="w-full h-11 px-3 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 placeholder:text-gray-500 outline-none focus:border-violet-500/40"
                    required
                  />
                  <p className="mt-1 text-[11px] text-gray-500">Можно вставлять URL без `https://`</p>
                </div>
                <div>
                  <label className="block text-xs text-gray-400 mb-1.5">Заголовок</label>
                  <input
                    value={title}
                    onChange={(event) => setTitle(event.target.value)}
                    placeholder="Название ссылки"
                    className="w-full h-11 px-3 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 placeholder:text-gray-500 outline-none focus:border-violet-500/40"
                  />
                </div>
                <div>
                  <label className="block text-xs text-gray-400 mb-1.5">Описание</label>
                  <textarea
                    value={description}
                    onChange={(event) => setDescription(event.target.value)}
                    rows={2}
                    placeholder="Необязательно"
                    className="w-full px-3 py-2.5 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 placeholder:text-gray-500 outline-none focus:border-violet-500/40 resize-none"
                  />
                </div>
              </div>
            </div>

            <div className="rounded-xl border border-white/10 bg-white/[0.02] p-4">
              <div className="flex items-start justify-between gap-4">
                <div className="space-y-1">
                  <p className="text-sm text-gray-200 flex items-center gap-2">
                    <Bell className="w-4 h-4 text-[#2AABEE]" />
                    Уведомления о кликах в Telegram
                  </p>
                  <p className="text-xs text-gray-500">
                    По умолчанию выключено. Можно включить отдельно для этой ссылки.
                  </p>
                  {!telegramClickStatus.featureAvailableByPlan ? (
                    <p className="text-xs text-amber-300">Доступно на тарифе Lite и выше.</p>
                  ) : isTelegramStatusLoading ? (
                    <p className="text-xs text-gray-400">Проверяем настройки Telegram...</p>
                  ) : telegramClickStatus.hasBotToken ? (
                    <p className="text-xs text-emerald-300">Токен бота настроен.</p>
                  ) : (
                    <p className="text-xs text-amber-300">
                      Токен бота не настроен. Добавьте токен в настройках профиля.
                    </p>
                  )}
                </div>

                <button
                  type="button"
                  aria-label="Переключить Telegram-уведомления о кликах"
                  aria-pressed={telegramClickNotificationsEnabled}
                  onClick={() => handleToggleTelegramNotifications(!telegramClickNotificationsEnabled)}
                  disabled={!telegramClickStatus.featureAvailableByPlan || isTelegramStatusLoading}
                  className={`relative inline-flex h-6 w-11 shrink-0 items-center rounded-full border transition-all duration-300 ${
                    telegramClickNotificationsEnabled
                      ? 'border-violet-400/60 bg-violet-500/30'
                      : 'border-white/10 bg-white/5'
                  } ${!telegramClickStatus.featureAvailableByPlan || isTelegramStatusLoading ? 'cursor-not-allowed opacity-50' : ''}`}
                >
                  <span
                    className={`inline-block h-5 w-5 transform rounded-full bg-white shadow-[0_0_14px_rgba(255,255,255,0.25)] transition-transform duration-300 ${
                      telegramClickNotificationsEnabled ? 'translate-x-[20px]' : 'translate-x-[2px]'
                    }`}
                  />
                </button>
              </div>
            </div>

            <div className="rounded-xl border border-white/10 bg-white/[0.02] p-4">
              <button
                type="button"
                onClick={() => setShowAdvanced((prev) => !prev)}
                className="w-full inline-flex items-center justify-between text-left"
              >
                <span className="text-sm text-gray-200 font-medium">Расширенные настройки</span>
                <span className="text-xs text-gray-500">{showAdvanced ? 'Скрыть' : 'Открыть'}</span>
              </button>

              {showAdvanced ? (
                <div className="mt-3 space-y-3">
                  {planFeatures.customSlug ? (
                    <div>
                      <label className="block text-xs text-gray-400 mb-1.5">Кастомный slug</label>
                      <input
                        value={customSlug}
                        onChange={(event) => setCustomSlug(event.target.value)}
                        placeholder="my-link"
                        className="w-full h-10 px-3 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 placeholder:text-gray-500 outline-none focus:border-violet-500/40"
                      />
                    </div>
                  ) : null}

                  <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
                    {planFeatures.expiresAt ? (
                      <div>
                        <label className="block text-xs text-gray-400 mb-1.5">Срок действия</label>
                        <input
                          type="datetime-local"
                          value={expiresAtInput}
                          onChange={(event) => setExpiresAtInput(event.target.value)}
                          max="9999-12-31T23:59"
                          className="w-full h-10 px-3 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 outline-none focus:border-violet-500/40"
                        />
                        <p className="mt-1 text-[11px] text-gray-500">
                          Время указывается в таймзоне проекта: {projectTimeZone}
                        </p>
                      </div>
                    ) : null}
                    {planFeatures.clickLimit ? (
                      <div>
                        <label className="block text-xs text-gray-400 mb-1.5">Лимит кликов</label>
                        <input
                          type="number"
                          min={1}
                          value={clickLimitInput}
                          onChange={(event) => setClickLimitInput(event.target.value)}
                          placeholder="Например 1000"
                          className="w-full h-10 px-3 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 placeholder:text-gray-500 outline-none focus:border-violet-500/40"
                        />
                      </div>
                    ) : null}
                  </div>

                  {planFeatures.password ? (
                    <div>
                      <label className="block text-xs text-gray-400 mb-1.5">Пароль на ссылку</label>
                      <input
                        type="password"
                        minLength={4}
                        value={passwordInput}
                        onChange={(event) => setPasswordInput(event.target.value)}
                        placeholder="Минимум 4 символа"
                        className="w-full h-10 px-3 rounded-lg border border-white/10 bg-black/40 text-sm text-gray-100 placeholder:text-gray-500 outline-none focus:border-violet-500/40"
                      />
                    </div>
                  ) : null}

                  {planFeatures.manualOgEditing ? (
                    <OGEditor
                      ogTitle={ogEditorData.ogTitle}
                      ogDescription={ogEditorData.ogDescription}
                      ogImage={ogEditorData.ogImage}
                      shortUrl={shortUrlPreview}
                      mode={ogMode}
                      onModeChange={setOgMode}
                      onUploadStateChange={setIsOgUploading}
                      onChange={(data) => setOgEditorData((prev) => ({ ...prev, ...data }))}
                    />
                  ) : null}

                  {!hasAdvancedAccess(planFeatures) ? (
                    <p className="text-xs text-amber-300">Недоступно на текущем тарифе.</p>
                  ) : null}
                </div>
              ) : null}
            </div>

            <div className="rounded-xl border border-white/10 bg-white/[0.02] p-4 space-y-3">
              <TemplateSelector
                onSelect={handleApplyTemplate}
                refreshToken={templatesRefreshToken}
              />
              <UTMBuilder
                baseUrl={longUrl}
                utmParams={utmParams}
                onUTMChange={setUtmParams}
                onSaveTemplate={handleSaveTemplate}
                isOpen={isUtmOpen}
                onOpenChange={setIsUtmOpen}
              />
            </div>

            <ApiErrorAlert message={formError} />

            <div className="sticky bottom-0 pb-1 pt-2 bg-gradient-to-t from-[#0A0A0A] to-transparent">
              <button
                type="submit"
                disabled={isCreating || isOgUploading}
                className={`w-full h-11 rounded-xl text-sm font-semibold transition-all duration-200 inline-flex items-center justify-center gap-2 ${
                  isSuccess && !isCreating && !isOgUploading
                    ? 'bg-emerald-500/90 text-white'
                    : 'bg-gradient-to-r from-fuchsia-500 to-violet-600 text-white hover:opacity-95 disabled:opacity-65'
                }`}
              >
                {isCreating || isOgUploading ? (
                  <>
                    <Loader2 className="w-4 h-4 animate-spin" />
                    {isOgUploading ? 'Загрузка OG изображения...' : 'Создание ссылки...'}
                  </>
                ) : isSuccess ? (
                  <>
                    <span className="inline-flex w-4 h-4 rounded-full border border-white/30 items-center justify-center">✓</span>
                    Готово
                  </>
                ) : (
                  'Создать ссылку'
                )}
              </button>
            </div>
          </form>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );

  if (typeof document === 'undefined') {
    return dialogContent;
  }

  return createPortal(dialogContent, document.body);
}
