CCCPaste
import * as React from "react";
import {
  Modal,
  Form,
  Input,
  Button,
  message,
  Row,
  Col,
  Spin,
  DatePicker,
  Card,
  Space,
  Divider,
} from "antd";
import { PlusOutlined } from "@ant-design/icons";
import { useEmployeeSkillsDirectoryStore } from "../EmployeeSkillsDirectoryStore";
import { User } from "@microsoft/microsoft-graph-types";
import { EnhancedUser } from "../../../services/MSGraphService";
import { globalContext } from "../../../common/GlobalContext";
import CropModal from "./CropModal";
import dayjs from "dayjs";
import {
  SkillEntry,
  ExperienceEntry,
  EducationEntry,
} from "../../../services/SPServices/DAO/StaffListDAO";
import { SkillDefinition } from "../../../services/SPServices/DAO/SkillsListDAO";

import PhotoEditor from "./EditUser/PhotoEditor";
import TagEditor from "./EditUser/TagEditor";
import SkillsSection from "./EditUser/SkillsSection";
import ExperienceSection from "./EditUser/ExperienceSection";
import EducationSection from "./EditUser/EducationSection";

const { TextArea } = Input;

type Props = {
  isVisible: boolean;
  selectedUser: EnhancedUser | null;
  onClose: () => void;
};

export default function EditUserModal({
  isVisible,
  selectedUser,
  onClose,
}: Props) {
  const [form] = Form.useForm();

  const skillsSectionRef = React.useRef(null);
  const experienceSectionRef = React.useRef(null);
  const educationSectionRef = React.useRef(null);

  const {
    updateUser,
    getUserDetails,
    getCurrentUserPhotoBlob,
    updateCurrentUserPhoto,
    deleteCurrentUserPhoto,
    getSkillsDictionary,
    getStaffItemById,
    saveProfile,
  } = useEmployeeSkillsDirectoryStore();

  const { spfxContext } = React.useContext(globalContext);

  const [loading, setLoading] = React.useState(false);
  const [detailsLoading, setDetailsLoading] = React.useState(false);
  const [photoLoading, setPhotoLoading] = React.useState(false);
  const [skillsLoading, setSkillsLoading] = React.useState(false);

  const [availableSkills, setAvailableSkills] = React.useState<
    SkillDefinition[]
  >([]);
  const [userSkills, setUserSkills] = React.useState([]);
  const [experience, setExperience] = React.useState([]);
  const [education, setEducation] = React.useState([]);

  const [interests, setInterests] = React.useState([]);
  const [projects, setProjects] = React.useState([]);
  const [schools, setSchools] = React.useState([]);
  const [skills, setSkills] = React.useState([]);
  const [userEmail, setUserEmail] = React.useState("");
  const [imageFile, setImageFile] = React.useState(null);
  const [currentPhotoUrl, setCurrentPhotoUrl] = React.useState(
    null
  );
  const [isCropModalOpen, setIsCropModalOpen] = React.useState(false);
  const [tempImageUrl, setTempImageUrl] = React.useState(null);
  const [isAdmin, setIsAdmin] = React.useState(false);
  const context = React.useContext(globalContext);


const canEdit = React.useMemo(() => {
  if (!selectedUser) return false;
  const currentUserEmail = (spfxContext.pageContext.user.email || "").toLowerCase();
  const selMail = (selectedUser.mail || selectedUser.userPrincipalName || "").toLowerCase();
  const isOwner = selMail && currentUserEmail && (selMail === currentUserEmail);
  return isOwner || isAdmin;
}, [selectedUser, spfxContext, isAdmin]);


  const uniq = (arr: readonly string[]) =>
    Array.from(new Set(arr.map((x) => (x ?? "").trim()).filter(Boolean)));
  const titlesFromUserSkills = (items: readonly SkillEntry[]) =>
    items.map((s) => s.title || "").filter((t) => t.trim().length > 0);
  const schoolsFromEducation = (items: readonly EducationEntry[]) =>
    items.map((e) => e.institution || "").filter((t) => t.trim().length > 0);

React.useEffect(() => {
  if (!selectedUser || !isVisible) return;
  let mounted = true;

  (async () => {
    try {
      setDetailsLoading(true);
      setSkillsLoading(true);

      // 1. Skills dictionary
      const dict = await getSkillsDictionary();
      if (!mounted) return;
      setAvailableSkills(dict || []);
      setSkillsLoading(false);

      // 2. User details
      const details = await getUserDetails(selectedUser.id!);

      if (!mounted) return;
      form.setFieldsValue({
        aboutMe: details.aboutMe || "",
        birthday: details.birthday ? dayjs(details.birthday) : null,
        mobilePhone: details.mobilePhone || "",
        businessPhone: details.businessPhones?.[0] || "",
        jobTitle: details.jobTitle || "",
        companyName: details.companyName || "",
        department: details.department || "",
        city: details.city || "",
      });
      setInterests(details.interests || []);
      setSkills(uniq(details.skills || []));
      setSchools(uniq(details.schools || []));
      setCurrentPhotoUrl(details.photoUrl);
      setUserEmail(details.userPrincipalName || details.mail || "");

      const staff = await getStaffItemById(details.id!);
      if (!mounted) return;
      if (staff) {
        setUserSkills(staff.Skills || []);
        setExperience(staff.Experience || []);
        setEducation(staff.Education || []);
        setProjects(uniq(staff.Projects || []));
      }
      
      console.log('details', details);
      try {
        const adminsRes: any = await (context as any).sp.adminDAO.getAdmins();
        if (!mounted) return;

        const adminsArr: any[] = Array.isArray(adminsRes)
          ? adminsRes
          : Array.isArray(adminsRes?.PromiseResult)
          ? adminsRes.PromiseResult
          : [];

        const currentEmail = (spfxContext.pageContext.user.email || "").toLowerCase();
        const currentId = (spfxContext.pageContext.user.loginName || "") || null;

        const found = adminsArr.some((a: any) => {
          const adminEmail = (a.AdminUserEmail ?? a.Title ?? "").toLowerCase();
          const adminId = a.AdminUserId ?? a.Id ?? null;
          if (adminEmail && currentEmail && adminEmail === currentEmail) return true;
          if (adminId && currentId && String(adminId) === String(currentId)) return true;
          return false;
        });

        if (!mounted) return;
        setIsAdmin(Boolean(found));
      } catch (admErr) {
        console.error("Failed to load admins", admErr);
        if (mounted) setIsAdmin(false);
      }

      // 5. Photo: якщо власник (canEdit за власником) — підвантажуємо поточне фото користувача,
      // якщо адмін і редагує чужий профіль — намагаємось отримати фото selectedUser (якщо API підтримує)
      if (canEdit) {
        setPhotoLoading(true);
        const url = await getCurrentUserPhotoBlob();
        if (mounted) setCurrentPhotoUrl(url);
      } else if (isAdmin) {
        // пробуємо отримати фото для selectedUser через getUserDetails response або інший API
        // якщо у вас є метод отримати фото за id/email для будь-якого користувача — викличте його тут.
        // Інакше залишаємо photoUrl з details (встановлено вище).
        try {
          setPhotoLoading(true);
          // приклад: const url = await getPhotoForUser(selectedUser.id || selectedUser.userPrincipalName);
          // якщо такого методу немає — пропускаємо
          // const url = await getPhotoForUser(selectedUser.id || selectedUser.userPrincipalName || "");
          // if (mounted && url) setCurrentPhotoUrl(url);
        } catch (photoErr) {
          console.warn("Could not load photo for selected user", photoErr);
        } finally {
          if (mounted) setPhotoLoading(false);
        }
      }
    } catch (e) {
      console.error(e);
      message.error("Не вдалося завантажити дані користувача");
    } finally {
      if (mounted) {
        setDetailsLoading(false);
        setPhotoLoading(false);
        setSkillsLoading(false);
      }
    }
  })();

  return () => {
    mounted = false;
  };
}, [selectedUser, isVisible, canEdit, getSkillsDictionary, getUserDetails, getStaffItemById, getCurrentUserPhotoBlob, spfxContext, context]);

  const syncGraphSkills = async (nextUserSkills: SkillEntry[] = userSkills) => {
    const merged = uniq(titlesFromUserSkills(nextUserSkills));
    setSkills(merged);
    await updateUser(selectedUser?.id || "", {
      skills: merged,
    } as Partial);
  };
  const syncGraphSchools = async (
    nextEducation: EducationEntry[] = education
  ) => {
    const merged = uniq(schoolsFromEducation(nextEducation));
    setSchools(merged);
    await updateUser(selectedUser?.id || "", {
      schools: merged,
    } as Partial);
  };
  const syncGraphProjects = async (nextProjects: string[] = projects) => {
    const merged = uniq(nextProjects);
    await updateUser(selectedUser?.id || "", {
      pastProjects: merged,
    } as Partial);
  };

  const handleSubmit = async () => {
    try {
      setLoading(true);
      const v = await form.validateFields();

      // Створюємо об'єкт лише з заповненими полями
      const profileData: any = {
        userId: selectedUser?.id || selectedUser?.userPrincipalName || "",
        email: userEmail,
        interests,
        projects,
        staffSkills: userSkills,
        education,
        experience,
      };

      // Додаємо лише заповнені поля
      if (v.aboutMe?.trim()) profileData.aboutMe = v.aboutMe.trim();
      if (v.birthday) profileData.birthday = v.birthday.format("YYYY-MM-DD");
      if (v.mobilePhone?.trim()) profileData.mobilePhone = v.mobilePhone.trim();
      if (v.businessPhone?.trim()) profileData.businessPhone = v.businessPhone.trim();
      if (v.jobTitle?.trim()) profileData.jobTitle = v.jobTitle.trim();
      if (v.companyName?.trim()) profileData.companyName = v.companyName.trim();
      if (v.department?.trim()) profileData.department = v.department.trim();
      if (v.city?.trim()) profileData.city = v.city.trim();

      await saveProfile(profileData);

      if (imageFile && canEdit) {
        await updateCurrentUserPhoto(imageFile);
      }

      message.success("Profile updated!");
      onClose();
    } catch (e) {
      console.error(e);
      message.error("Error updating profile!");
    } finally {
      setLoading(false);
    }
  };

  const handleCancel = () => {
    form.resetFields();
    setSkills([]);
    setSchools([]);
    setInterests([]);
    setProjects([]);
    setUserSkills([]);
    setExperience([]);
    setEducation([]);
    setImageFile(null);
    setCurrentPhotoUrl(null);
    onClose();
  };

  const formatDate = (s: string) => dayjs(s).format("MMM YYYY");

  const cardStyle = {
    marginBottom: 4,
    borderRadius: 8,
    boxShadow: "0 1px 3px rgba(0, 0, 0, 0.1)",
  };

  const sectionHeaderStyle = {
    backgroundColor: "#fafafa",
    borderRadius: "8px 8px 0 0",
    padding: "8px",
    margin: "-1px -1px 16px -1px",
    borderBottom: "1px solid #f0f0f0",
    display: "flex",
    justifyContent: "space-between",
    alignItems: "center",
  };

  return (
    
          {canEdit ? "Edit your profile" : "View Profile"}
        
} open={isVisible} onCancel={handleCancel} footer={ canEdit ? [ , , ] : [ , ] } width={1400} destroyOnHidden > { setTempImageUrl(currentPhotoUrl); setIsCropModalOpen(true); }} />

Basic Information