import { useEffect, useRef, useState } from "react";
import { KeyRound, Save, Upload, X } from "lucide-react";
import type { LauncherUser } from "../../entities/user/types";
import { uploadStorageFile } from "../../shared/api/storageApi";
import { initials } from "../../shared/lib/format";
import { Button, IconButton } from "../../shared/ui/Button";

export function ProfileSettingsPanel({
  user,
  onClose,
  onSaveProfile,
  onChangePassword,
}: {
  user: LauncherUser;
  onClose: () => void;
  onSaveProfile: (patch: Partial<LauncherUser>) => Promise<void>;
  onChangePassword: (newPassword: string) => Promise<void>;
}) {
  const [draft, setDraft] = useState<LauncherUser>(user);
  const [avatarPreviewUrl, setAvatarPreviewUrl] = useState<string | null>(user.avatarUrl ?? null);
  const [newPassword, setNewPassword] = useState("");
  const [uploading, setUploading] = useState(false);
  const [savingProfile, setSavingProfile] = useState(false);
  const [savingPassword, setSavingPassword] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const draftRef = useRef(draft);
  const hasUnsavedProfileChangesRef = useRef(false);
  const lastSyncedUserIdRef = useRef(user.id);

  useEffect(() => {
    draftRef.current = draft;
  }, [draft]);

  useEffect(() => {
    const isAnotherUser = lastSyncedUserIdRef.current !== user.id;

    if (!isAnotherUser && hasUnsavedProfileChangesRef.current) {
      return;
    }

    lastSyncedUserIdRef.current = user.id;
    hasUnsavedProfileChangesRef.current = false;
    setDraft(user);
    setAvatarPreviewUrl(user.avatarUrl ?? null);
    setUploading(false);
  }, [user]);

  useEffect(
    () => () => {
      if (avatarPreviewUrl?.startsWith("blob:")) {
        URL.revokeObjectURL(avatarPreviewUrl);
      }
    },
    [avatarPreviewUrl]
  );

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === "Escape") onClose();
    };

    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [onClose]);

  function update<K extends keyof LauncherUser>(key: K, value: LauncherUser[K]) {
    hasUnsavedProfileChangesRef.current = true;
    setDraft((current) => {
      const nextDraft = { ...current, [key]: value };
      draftRef.current = nextDraft;
      return nextDraft;
    });
  }

  async function handleAvatarUpload(file: File | undefined) {
    if (!file) return;

    const localPreviewUrl = URL.createObjectURL(file);
    hasUnsavedProfileChangesRef.current = true;
    setAvatarPreviewUrl(localPreviewUrl);
    setUploading(true);
    setMessage(null);

    try {
      const result = await uploadStorageFile(file);
      update("avatarUrl", result.url);
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Не удалось загрузить аватар");
      setAvatarPreviewUrl(draftRef.current.avatarUrl ?? null);
    } finally {
      setUploading(false);
    }
  }

  async function handleSaveProfile() {
    setSavingProfile(true);
    setMessage(null);

    try {
      const profileDraft = draftRef.current;
      await onSaveProfile({
        name: profileDraft.name,
        email: profileDraft.email,
        phone: profileDraft.phone ?? null,
        position: profileDraft.position ?? null,
        avatarUrl: profileDraft.avatarUrl ?? null,
      });
      hasUnsavedProfileChangesRef.current = false;
      setAvatarPreviewUrl(profileDraft.avatarUrl ?? null);
      setMessage("Профиль сохранён");
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Не удалось сохранить профиль");
    } finally {
      setSavingProfile(false);
    }
  }

  async function handleSavePassword() {
    if (newPassword.length < 8) {
      setMessage("Пароль должен быть не короче 8 символов");
      return;
    }

    setSavingPassword(true);
    setMessage(null);

    try {
      await onChangePassword(newPassword);
      setNewPassword("");
      setMessage("Пароль обновлён");
    } catch (error) {
      setMessage(error instanceof Error ? error.message : "Не удалось обновить пароль");
    } finally {
      setSavingPassword(false);
    }
  }

  return (
    <aside className="profile-settings-layer" aria-label="Настройки профиля">
      <section className="profile-settings-panel">
        <div className="profile-settings-panel__head">
          <div>
            <p className="eyebrow">Профиль</p>
            <h2>Настройки</h2>
          </div>
          <IconButton label="Закрыть настройки" className="admin-panel-close" type="button" onClick={onClose}>
            <X size={15} strokeWidth={1.45} />
          </IconButton>
        </div>

        <div className="profile-settings-panel__body">
          <div className="profile-settings-avatar-card">
            {avatarPreviewUrl ? (
              <img className="profile-settings-avatar-card__image" src={avatarPreviewUrl} alt="" />
            ) : (
              <span className="profile-settings-avatar-card__image">{initials(draft.name)}</span>
            )}
            <label className="profile-settings-upload">
              <Upload size={15} />
              <span>{uploading ? "Загружаем" : "Загрузить аватар"}</span>
              <input
                type="file"
                accept="image/png,image/jpeg,image/webp,image/gif"
                disabled={uploading}
                onChange={(event) => {
                  const file = event.currentTarget.files?.[0];
                  event.currentTarget.value = "";
                  void handleAvatarUpload(file);
                }}
              />
            </label>
          </div>

          <label className="profile-settings-field">
            <span>Имя</span>
            <input value={draft.name} onChange={(event) => update("name", event.target.value)} />
          </label>
          <label className="profile-settings-field">
            <span>Email</span>
            <input value={draft.email} onChange={(event) => update("email", event.target.value)} />
          </label>
          <label className="profile-settings-field">
            <span>Телефон</span>
            <input value={draft.phone ?? ""} onChange={(event) => update("phone", event.target.value || null)} />
          </label>
          <label className="profile-settings-field">
            <span>Должность</span>
            <input value={draft.position ?? ""} onChange={(event) => update("position", event.target.value || null)} />
          </label>

          <div className="profile-settings-divider" />

          <label className="profile-settings-field">
            <span>Новый пароль</span>
            <input
              value={newPassword}
              type="password"
              placeholder="Минимум 8 символов"
              onChange={(event) => setNewPassword(event.target.value)}
            />
          </label>
        </div>

        {message ? <p className="profile-settings-message">{message}</p> : null}

        <div className="profile-settings-panel__foot">
          <Button
            variant="secondary"
            surface="modal"
            type="button"
            icon={<KeyRound size={16} />}
            disabled={savingPassword || !newPassword}
            onClick={() => void handleSavePassword()}
          >
            {savingPassword ? "Обновляем" : "Сменить пароль"}
          </Button>
          <Button
            variant="accent"
            surface="modal"
            type="button"
            icon={<Save size={16} />}
            disabled={savingProfile || uploading}
            onClick={() => void handleSaveProfile()}
          >
            {savingProfile ? "Сохраняем" : "Сохранить"}
          </Button>
        </div>
      </section>
    </aside>
  );
}
