'use client';

import { useState, useCallback, useEffect, useRef } from 'react';
import { useToast } from './ToastProvider';
import ApiErrorAlert from './ApiErrorAlert';
import { getResponseErrorTextWithRequestId } from '@/lib/api-client';
import { datetimeLocalToIso, formatForDatetimeLocalInput } from '@/lib/datetime-local';
import { getRuntimeClientConfig } from '@/lib/runtime-client-config';
import type { PlanFeatures } from '@/lib/plans/types';

interface LinkEditModalProps {
  link: {
    id: string;
    shortUrl: string;
    longUrl: string;
    title: string | null;
    description: string | null;
    ogTitle: string | null;
    ogDescription: string | null;
    ogImage: string | null;
    expiresAt?: string | null;
    clickLimit?: number | null;
    hasPassword?: boolean;
  };
  planFeatures?: PlanFeatures;
  onClose: () => void;
  onSave: () => void;
}

const DEFAULT_PLAN_FEATURES: PlanFeatures = {
  customSlug: false,
  password: false,
  expiresAt: false,
  clickLimit: false,
  telegramClickNotifications: false,
  bulkActions: false,
  csvExport: false,
  pdfExport: false,
  manualOgEditing: false,
};

export default function LinkEditModal({ link, planFeatures = DEFAULT_PLAN_FEATURES, onClose, onSave }: LinkEditModalProps) {
  const toast = useToast();
  const [title, setTitle] = useState(link.title || '');
  const [description, setDescription] = useState(link.description || '');
  const [ogTitle, setOgTitle] = useState(link.ogTitle || '');
  const [ogDescription, setOgDescription] = useState(link.ogDescription || '');
  const [ogImage, setOgImage] = useState(link.ogImage || '');
  const projectTimeZone = getRuntimeClientConfig().timeZone;
  const initialExpiresAt = formatForDatetimeLocalInput(link.expiresAt ?? null, projectTimeZone);
  const [expiresAt, setExpiresAt] = useState(initialExpiresAt);
  const [hasInvalidExpiresAt, setHasInvalidExpiresAt] = useState(Boolean(link.expiresAt) && !initialExpiresAt);
  const [clickLimit, setClickLimit] = useState(
    typeof link.clickLimit === 'number' && link.clickLimit > 0 ? String(link.clickLimit) : ''
  );
  const [password, setPassword] = useState('');
  const [clearPassword, setClearPassword] = useState(false);
  const [isUploading, setIsUploading] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [error, setError] = useState('');
  const [localPreviewImage, setLocalPreviewImage] = useState('');
  const localPreviewRef = useRef<string | null>(null);

  const clearLocalPreview = useCallback(() => {
    if (localPreviewRef.current) {
      URL.revokeObjectURL(localPreviewRef.current);
      localPreviewRef.current = null;
    }
    setLocalPreviewImage('');
  }, []);

  useEffect(() => {
    return () => {
      if (localPreviewRef.current) {
        URL.revokeObjectURL(localPreviewRef.current);
      }
    };
  }, []);

  const handleImageUpload = useCallback(async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    if (!file.type.startsWith('image/')) {
      toast.error('Пожалуйста, выберите изображение');
      return;
    }

    const maxSize = 5 * 1024 * 1024;
    if (file.size > maxSize) {
      toast.error('Размер файла не должен превышать 5MB');
      return;
    }

    clearLocalPreview();
    const objectUrl = URL.createObjectURL(file);
    localPreviewRef.current = objectUrl;
    setLocalPreviewImage(objectUrl);

    setIsUploading(true);

    try {
      const formData = new FormData();
      formData.append('image', file);

      const response = await fetch('/api/og-image', {
        method: 'POST',
        body: formData,
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Ошибка загрузки'));
      }

      const data = await response.json();

      setOgImage(data.url);
      toast.success('Изображение загружено');
    } catch (err: unknown) {
      clearLocalPreview();
      const message = err instanceof Error ? err.message : 'Не удалось загрузить изображение';
      toast.error(message);
    } finally {
      setIsUploading(false);
      e.target.value = '';
    }
  }, [clearLocalPreview, toast]);

  const previewImage = localPreviewImage || ogImage;

  const handleSave = async () => {
    setIsSaving(true);
    setError('');

    try {
      const payload: Record<string, unknown> = {
        title: title || null,
        description: description || null,
      };

      if (planFeatures.manualOgEditing) {
        payload.ogTitle = ogTitle || null;
        payload.ogDescription = ogDescription || null;
        payload.ogImage = ogImage || null;
      }

      if (planFeatures.expiresAt) {
        if (hasInvalidExpiresAt && !expiresAt.trim()) {
          throw new Error('Текущий срок действия ссылки некорректен. Укажите дату заново.');
        }
        payload.expiresAt = datetimeLocalToIso(expiresAt, projectTimeZone);
      }

      if (planFeatures.clickLimit) {
        payload.clickLimit = clickLimit ? Number(clickLimit) : null;
      }

      if (planFeatures.password) {
        payload.password = clearPassword ? null : (password ? password : undefined);
      }

      const response = await fetch(`/api/links/${link.id}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        throw new Error(await getResponseErrorTextWithRequestId(response, 'Ошибка сохранения'));
      }

      const data = await response.json();

      toast.success('Ссылка обновлена');
      onSave();
    } catch (err: unknown) {
      const message = err instanceof Error ? err.message : 'Ошибка при сохранении';
      setError(message);
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
      <button
        type="button"
        aria-label="Закрыть окно редактирования"
        onClick={onClose}
        className="absolute inset-0 bg-black/50"
      />
      <div className="relative bg-bg-primary rounded-xl border border-text-secondary/10 p-4 sm:p-6 max-w-lg w-full max-h-[90vh] overflow-y-auto scrollbar-soft animate-scale-up">
        <h3 className="text-lg font-semibold text-text-primary mb-4">Редактировать ссылку</h3>

        <div className="space-y-4">
          {/* Заголовок */}
          <div>
            <label className="block text-sm font-medium text-text-secondary mb-2">
              Заголовок
            </label>
            <input
              type="text"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="Заголовок ссылки"
              className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent"
            />
          </div>

          {/* Описание */}
          <div>
            <label className="block text-sm font-medium text-text-secondary mb-2">
              Описание
            </label>
            <textarea
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder="Описание ссылки"
              rows={3}
              className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent resize-none"
            />
          </div>

          {planFeatures.manualOgEditing ? (
            <>
              {/* OG Заголовок */}
              <div>
                <label className="block text-sm font-medium text-text-secondary mb-2">
                  OG Заголовок (для соцсетей)
                </label>
                <input
                  type="text"
                  value={ogTitle}
                  onChange={(e) => setOgTitle(e.target.value)}
                  placeholder="Заголовок для соцсетей"
                  className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent"
                />
              </div>

              {/* OG Описание */}
              <div>
                <label className="block text-sm font-medium text-text-secondary mb-2">
                  OG Описание (для соцсетей)
                </label>
                <textarea
                  value={ogDescription}
                  onChange={(e) => setOgDescription(e.target.value)}
                  placeholder="Описание для соцсетей"
                  rows={2}
                  className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent resize-none"
                />
              </div>

              {/* OG Картинка */}
              <div>
                <label className="block text-sm font-medium text-text-secondary mb-2">
                  OG Картинка
                </label>
                <div className="flex flex-wrap items-center gap-3 mb-3">
                  <label className="w-full sm:w-auto flex items-center justify-center gap-2 px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-secondary hover:border-accent/50 hover:text-accent-light transition-colors cursor-pointer">
                    {isUploading ? (
                      <>
                        <div className="w-4 h-4 border-2 border-accent border-t-transparent rounded-full animate-spin"/>
                        Загрузка...
                      </>
                    ) : (
                      <>
                        <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
                          <polyline points="17 8 12 3 7 8"/>
                          <line x1="12" y1="3" x2="12" y2="15"/>
                        </svg>
                        Загрузить
                      </>
                    )}
                    <input
                      type="file"
                      accept="image/*"
                      onChange={handleImageUpload}
                      disabled={isUploading}
                      className="hidden"
                    />
                  </label>
                  {previewImage && (
                    <button
                      type="button"
                      onClick={() => {
                        setOgImage('');
                        clearLocalPreview();
                      }}
                      className="p-2.5 text-text-muted hover:text-error hover:bg-error/10 rounded-lg transition-colors"
                      title="Удалить картинку"
                    >
                      <svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                        <line x1="18" y1="6" x2="6" y2="18"/>
                        <line x1="6" y1="6" x2="18" y2="18"/>
                      </svg>
                    </button>
                  )}
                </div>
                {previewImage && (
                  <div className="relative w-full max-w-xs aspect-video rounded-lg overflow-hidden bg-bg-secondary">
                    <div
                      role="img"
                      aria-label="OG Preview"
                      className="absolute inset-0 bg-center bg-cover"
                      style={{ backgroundImage: `url("${previewImage}")` }}
                    />
                  </div>
                )}
              </div>
            </>
          ) : (
            <div className="rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning">
              Ручное OG-редактирование недоступно на текущем тарифе.
            </div>
          )}

          {(planFeatures.expiresAt || planFeatures.clickLimit) ? (
            <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
              {planFeatures.expiresAt && (
                <div>
                  <label className="block text-sm font-medium text-text-secondary mb-2">
                    Срок действия
                  </label>
                  <input
                    type="datetime-local"
                    value={expiresAt}
                    onChange={(e) => {
                      setExpiresAt(e.target.value);
                      setHasInvalidExpiresAt(false);
                    }}
                    max="9999-12-31T23:59"
                    className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent"
                  />
                  {hasInvalidExpiresAt && (
                    <p className="mt-1 text-[11px] text-warning">
                      Найдена некорректная дата срока действия. Укажите её заново.
                    </p>
                  )}
                </div>
              )}
              {planFeatures.clickLimit && (
                <div>
                  <label className="block text-sm font-medium text-text-secondary mb-2">
                    Лимит кликов
                  </label>
                  <input
                    type="number"
                    min={1}
                    step={1}
                    value={clickLimit}
                    onChange={(e) => setClickLimit(e.target.value)}
                    placeholder="Без лимита"
                    className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent"
                  />
                </div>
              )}
            </div>
          ) : (
            <p className="text-xs text-warning">Срок действия и лимит кликов недоступны на текущем тарифе.</p>
          )}

          {planFeatures.password ? (
            <div>
              <label className="block text-sm font-medium text-text-secondary mb-2">
                Пароль ссылки
              </label>
              <input
                type="password"
                value={password}
                onChange={(e) => {
                  setPassword(e.target.value);
                  if (e.target.value) setClearPassword(false);
                }}
                minLength={4}
                placeholder={link.hasPassword ? 'Новый пароль или оставьте пустым' : 'Установить пароль'}
                className="w-full px-4 py-2.5 bg-bg-secondary border border-text-secondary/10 rounded-lg text-sm text-text-primary focus:outline-none focus:border-accent"
              />
              {link.hasPassword && (
                <label className="mt-2 inline-flex items-center gap-2 text-xs text-text-secondary">
                  <input
                    type="checkbox"
                    checked={clearPassword}
                    onChange={(e) => {
                      setClearPassword(e.target.checked);
                      if (e.target.checked) setPassword('');
                    }}
                  />
                  Удалить пароль
                </label>
              )}
            </div>
          ) : (
            <p className="text-xs text-warning">Защита ссылок паролем недоступна на текущем тарифе.</p>
          )}

          {/* Ошибка */}
          <ApiErrorAlert message={error} compact />
        </div>

        {/* Кнопки */}
        <div className="flex flex-col sm:flex-row gap-3 mt-6">
          <button
            onClick={onClose}
            disabled={isSaving}
            className="flex-1 px-4 py-2.5 bg-bg-secondary text-text-secondary rounded-lg text-sm font-medium hover:bg-bg-primary transition-colors disabled:opacity-50"
          >
            Отмена
          </button>
          <button
            onClick={handleSave}
            disabled={isSaving}
            className="flex-1 px-4 py-2.5 bg-accent text-white rounded-lg text-sm font-medium hover:bg-accent-dark transition-colors disabled:opacity-50"
          >
            {isSaving ? 'Сохранение...' : 'Сохранить'}
          </button>
        </div>
      </div>
    </div>
  );
}
