import json
import time
import tkinter as tk
from datetime import datetime
from pathlib import Path
from tkinter import messagebox, scrolledtext

from core.notify import desktop_notify

from core.constants import DATA_DIR
from core.storage import save_enterprise, save_crm
from core.sync_queue import enqueue_sync_event
from core.ui import ToolTip, center_window, create_button, create_card, show_empty


class EnterprisePage:
    def __init__(self, app, parent):
        self.app = app
        self.colors = app.colors
        self.frame = tk.Frame(parent, bg=self.colors["bg"])
        self.selected_employee_id = None
        self.selected_goal_id = None
        self.employee_rows = []
        self._build()

    def _build(self):
        layout = tk.Frame(self.frame, bg=self.colors["bg"])
        layout.pack(fill=tk.BOTH, expand=True)
        self.active_module = "overview"
        self.module_tabs = {}
        self.module_bar = tk.Frame(layout, bg=self.colors["bg"])
        self.module_bar.pack(fill=tk.X, pady=(0, 12))
        self._build_module_tabs()

        body = tk.Frame(layout, bg=self.colors["bg"])
        body.pack(fill=tk.BOTH, expand=True)
        self.left = tk.Frame(body, bg=self.colors["bg"])
        self.left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        self.right = tk.Frame(body, bg=self.colors["bg"], width=390)
        self.right.pack(side=tk.RIGHT, fill=tk.BOTH, padx=(14, 0))
        self.right.pack_propagate(False)

        self.summary_card = create_card(self.left, self.colors)
        self.company_card = create_card(self.left, self.colors)
        self.stats_card = create_card(self.left, self.colors)
        self.goals_card = create_card(self.left, self.colors)
        self.employee_card = create_card(self.left, self.colors)
        self.org_card = create_card(self.right, self.colors)
        self.notice_card = create_card(self.right, self.colors)
        self.crm_card = create_card(self.left, self.colors)

        self._build_workspace_summary()
        self._build_company_area()
        self._build_stats()
        self._build_goals_area()
        self._build_employee_area()
        self._build_org_area()
        self._build_notice_area()
        self._build_crm_area()
        self._show_module("overview")

    def _build_module_tabs(self):
        for child in self.module_bar.winfo_children():
            child.destroy()
        self.module_tabs = {}
        for module, key in [
            ("overview", "enterprise_tab_overview"),
            ("goals", "enterprise_tab_goals"),
            ("employees", "enterprise_tab_employees"),
            ("org", "enterprise_tab_org"),
            ("notices", "enterprise_tab_notices"),
            ("crm", "enterprise_tab_crm"),
        ]:
            btn = tk.Button(
                self.module_bar,
                text=self.app.t(key),
                command=lambda m=module: self._show_module(m),
                relief=tk.FLAT,
                bd=0,
                font=("Microsoft YaHei UI", 10, "bold"),
                padx=16,
                pady=9,
                cursor="hand2",
            )
            btn.pack(side=tk.LEFT, padx=(0, 8))
            self.module_tabs[module] = btn
        tk.Label(
            self.module_bar,
            text=self.app.t("enterprise_tab_hint"),
            font=("Microsoft YaHei UI", 9),
            fg=self.colors["text_secondary"],
            bg=self.colors["bg"],
        ).pack(side=tk.LEFT, padx=(8, 0))

    def _show_module(self, module):
        self.active_module = module
        for btn_key, btn in self.module_tabs.items():
            active = btn_key == module
            btn.config(
                bg=self.colors["primary"] if active else self.colors["card"],
                fg="white" if active else self.colors["text"],
                activebackground=self.colors["primary_dark"] if active else self.colors["primary_light"],
                activeforeground="white" if active else self.colors["primary"],
            )
        for card in (self.summary_card, self.company_card, self.stats_card, self.goals_card, self.employee_card, self.org_card, self.notice_card, self.crm_card):
            try:
                card.pack_forget()
            except Exception:
                pass
        try:
            self.left.pack_forget()
            self.right.pack_forget()
        except Exception:
            pass
        try:
            self.right.pack_propagate(False if module in ("overview", "employees") else True)
        except Exception:
            pass

        if module == "overview":
            self.left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            self.right.pack(side=tk.RIGHT, fill=tk.BOTH, padx=(14, 0))
            self.summary_card.pack(fill=tk.X, pady=(0, 14))
            self.company_card.pack(fill=tk.X, pady=(0, 14))
            self.stats_card.pack(fill=tk.X, pady=(0, 14))
            self.org_card.pack(fill=tk.BOTH, expand=True)
        elif module == "goals":
            self.left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            self.goals_card.pack(fill=tk.BOTH, expand=True)
        elif module == "employees":
            self.left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            self.right.pack(side=tk.RIGHT, fill=tk.BOTH, padx=(14, 0))
            self.employee_card.pack(fill=tk.BOTH, expand=True)
            self.org_card.pack(fill=tk.BOTH, expand=True)
        elif module == "org":
            self.right.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            self.org_card.pack(fill=tk.BOTH, expand=True)
        elif module == "notices":
            self.right.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            self.notice_card.pack(fill=tk.BOTH, expand=True)
        elif module == "crm":
            self.left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
            self.crm_card.pack(fill=tk.BOTH, expand=True)
        self.refresh()

    def _title(self, parent, key, subtitle_key=None):
        header = tk.Frame(parent, bg=self.colors["card"])
        header.pack(fill=tk.X, padx=18, pady=(16, 10))
        label = tk.Label(header, text=self.app.t(key), font=("Microsoft YaHei UI", 15, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        label.pack(anchor="w")
        subtitle = None
        if subtitle_key:
            subtitle = tk.Label(
                header,
                text=self.app.t(subtitle_key),
                font=("Microsoft YaHei UI", 9),
                fg=self.colors["text_secondary"],
                bg=self.colors["card"],
                wraplength=320,
                justify=tk.LEFT,
            )
            subtitle.pack(anchor="w", pady=(4, 0))
        return label, subtitle

    def _build_workspace_summary(self):
        body = tk.Frame(self.summary_card, bg=self.colors["card"])
        body.pack(fill=tk.BOTH, expand=True, padx=18, pady=16)
        left = tk.Frame(body, bg=self.colors["card"])
        left.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        self.summary_title = tk.Label(left, text=self.app.t("enterprise_overview_title"), font=("Microsoft YaHei UI", 15, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.summary_title.pack(anchor="w")
        self.summary_hint = tk.Label(left, text=self.app.t("enterprise_overview_hint"), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["card"], wraplength=580, justify=tk.LEFT)
        self.summary_hint.pack(anchor="w", pady=(4, 12))
        self.summary_stats = tk.Frame(left, bg=self.colors["card"])
        self.summary_stats.pack(fill=tk.X)
        self.summary_stat_widgets = []
        for _ in range(4):
            box = tk.Frame(self.summary_stats, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 8))
            value = tk.Label(box, text="", font=("Microsoft YaHei UI", 12, "bold"), fg=self.colors["primary"], bg=self.colors["card_soft"])
            value.pack(anchor="w", padx=12, pady=(10, 0))
            label = tk.Label(box, text="", font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["card_soft"])
            label.pack(anchor="w", padx=12, pady=(3, 10))
            self.summary_stat_widgets.append((box, value, label))

        right = tk.Frame(body, bg=self.colors["card"])
        right.pack(side=tk.RIGHT, padx=(16, 0), fill=tk.Y)
        self.summary_status = tk.Label(right, text="", font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["primary"], bg=self.colors["primary_light"], padx=12, pady=6)
        self.summary_status.pack(anchor="e")
        self.summary_primary_btn = create_button(right, self.app.t("enterprise_overview_open_notices"), lambda: self._show_module("notices"), self.colors, filled=True)
        self.summary_primary_btn.pack(fill=tk.X, pady=(12, 0))
        self.summary_secondary_btn = create_button(right, self.app.t("enterprise_overview_open_goals"), lambda: self._show_module("goals"), self.colors)
        self.summary_secondary_btn.pack(fill=tk.X, pady=(8, 0))

    def _refresh_workspace_summary(self):
        if not hasattr(self, "summary_stat_widgets"):
            return
        company_name = str(self.app.enterprise.get("company_name") or self.app.t("company_not_created")).strip()
        role_text = self.app.t("admin_badge") if self.app.is_admin() else self.app.t("normal_staff")
        joined_text = self.app.t("enterprise_joined") if self.user_enterprise_joined() else self.app.t("enterprise_access_status_not_member")
        invite_code = str(self.app.enterprise.get("company_invite_code") or "-").strip() if self.company_created() else "-"
        stats = [
            (company_name, self.app.t("enterprise_overview_stat_company")),
            (role_text, self.app.t("enterprise_overview_stat_role")),
            (joined_text, self.app.t("enterprise_overview_stat_access")),
            (invite_code, self.app.t("enterprise_overview_stat_invite")),
        ]
        for (box, value, label), (val, lab) in zip(self.summary_stat_widgets, stats):
            value.config(text=val)
            label.config(text=lab)
        self.summary_status.config(text=self.app.t("company_created") if self.company_created() else self.app.t("company_not_created"), fg=self.colors["success"] if self.company_created() else self.colors["warning"], bg=self.colors["success_light"] if self.company_created() else self.colors["warning_light"])
        if self.company_created() and hasattr(self, 'summary_primary_btn'):
            self.summary_primary_btn.config(state=tk.NORMAL if self.enterprise_access_ready() else tk.DISABLED)
        if hasattr(self, 'summary_secondary_btn'):
            self.summary_secondary_btn.config(state=tk.NORMAL if self.enterprise_access_ready() else tk.DISABLED)

    def _build_company_area(self):
        body = tk.Frame(self.company_card, bg=self.colors["card"])
        body.pack(fill=tk.X, padx=18, pady=16)
        left = tk.Frame(body, bg=self.colors["card"])
        left.pack(side=tk.LEFT, fill=tk.X, expand=True)
        self.company_title = tk.Label(left, text=self.app.t("company_section"), font=("Microsoft YaHei UI", 15, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.company_title.pack(anchor="w")
        row = tk.Frame(left, bg=self.colors["card"])
        row.pack(fill=tk.X, pady=(10, 0))
        self.company_label = tk.Label(row, text=self.app.t("company_name"), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card"])
        self.company_label.pack(side=tk.LEFT, padx=(0, 8))
        self.company_var = tk.StringVar(value=self.app.enterprise.get("company_name", ""))
        self.company_entry = tk.Entry(row, textvariable=self.company_var, relief=tk.FLAT, bd=0, bg=self.colors["bg"], fg=self.colors["text"], font=("Microsoft YaHei UI", 10))
        self.company_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, ipady=8)
        self.company_status = tk.Label(left, text="", font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["warning"], bg=self.colors["card"])
        self.company_status.pack(anchor="w", pady=(8, 0))

        access = tk.Frame(left, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
        access.pack(fill=tk.X, pady=(12, 0))
        self.access_title = tk.Label(access, text=self.app.t("enterprise_access_title"), font=("Microsoft YaHei UI", 11, "bold"), fg=self.colors["text"], bg=self.colors["card_soft"])
        self.access_title.pack(anchor="w", padx=12, pady=(10, 2))
        self.access_hint = tk.Label(access, text=self.app.t("enterprise_access_hint"), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["card_soft"], wraplength=760, justify=tk.LEFT)
        self.access_hint.pack(anchor="w", padx=12, pady=(0, 8))
        invite_row = tk.Frame(access, bg=self.colors["card_soft"])
        invite_row.pack(fill=tk.X, padx=12, pady=(0, 10))
        self.invite_code_label = tk.Label(invite_row, text=self.app.t("enterprise_invite_code"), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card_soft"])
        self.invite_code_label.pack(side=tk.LEFT, padx=(0, 8))
        self.invite_code_var = tk.StringVar(value="")
        self.invite_code_entry = tk.Entry(invite_row, textvariable=self.invite_code_var, relief=tk.FLAT, bd=0, bg=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 10))
        self.invite_code_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, ipady=7)
        self.join_company_btn = create_button(invite_row, self.app.t("enterprise_join_workspace"), self.join_workspace, self.colors)
        self.join_company_btn.pack(side=tk.LEFT, padx=(8, 0))
        self.invite_status = tk.Label(access, text="", font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card_soft"])
        self.invite_status.pack(anchor="w", padx=12, pady=(0, 10))

        actions = tk.Frame(body, bg=self.colors["card"])
        actions.pack(side=tk.RIGHT, padx=(14, 0))
        self.company_save_btn = create_button(actions, self.app.t("enterprise_create_workspace"), self.save_company, self.colors, filled=True)
        self.company_save_btn.pack(fill=tk.X)
        self.copy_invite_btn = create_button(actions, self.app.t("enterprise_copy_invite"), self.copy_invite_code, self.colors)
        self.copy_invite_btn.pack(fill=tk.X, pady=(8, 0))

    def _ensure_invite_code(self):
        code = str(self.app.enterprise.get("company_invite_code", "")).strip()
        if not code:
            prefix = "NEXA"
            stamp = str(int(time.time()))[-6:]
            code = f"{prefix}-{stamp}"
            self.app.enterprise["company_invite_code"] = code
        return code

    def save_company(self):
        if not self.app.require_admin():
            return
        name = self.company_var.get().strip()
        if not name:
            messagebox.showwarning(self.app.t("warning_title") if "warning_title" in self.app.lang else self.app.t("confirm_title"), self.app.t("company_required"))
            return
        self.app.enterprise["company_name"] = name
        self.app.enterprise["company_created"] = True
        self._ensure_invite_code()
        self.app.user_settings["enterprise_joined"] = True
        save_enterprise(self.app.enterprise)
        try:
            from core.storage import save_settings
            save_settings(self.app.user_settings)
        except Exception:
            pass
        self.app.set_status("company_saved")
        self.refresh()
        self.app.refresh_home()

    def join_workspace(self):
        if not self.company_created():
            messagebox.showwarning(self.app.t("company_required_title"), self.app.t("enterprise_need_company_first"))
            return
        expected = str(self.app.enterprise.get("company_invite_code", "")).strip()
        entered = self.invite_code_var.get().strip()
        if not expected:
            expected = self._ensure_invite_code()
            save_enterprise(self.app.enterprise)
        if not entered or entered != expected:
            messagebox.showwarning(self.app.t("confirm_title"), self.app.t("enterprise_invite_invalid"))
            return
        self.app.user_settings["enterprise_joined"] = True
        try:
            from core.storage import save_settings
            save_settings(self.app.user_settings)
        except Exception:
            pass
        self.app.set_status("enterprise_joined")
        messagebox.showinfo(self.app.t("success_title"), self.app.t("enterprise_joined"))
        self.refresh()

    def copy_invite_code(self):
        if not self.company_created():
            messagebox.showwarning(self.app.t("company_required_title"), self.app.t("enterprise_need_company_first"))
            return
        code = self._ensure_invite_code()
        save_enterprise(self.app.enterprise)
        try:
            self.app.root.clipboard_clear()
            self.app.root.clipboard_append(code)
            self.app.set_status("enterprise_invite_copied")
        except Exception:
            pass
        messagebox.showinfo(self.app.t("success_title"), self.app.t("enterprise_invite_copied"))

    def _build_stats(self):
        self.stats_body = tk.Frame(self.stats_card, bg=self.colors["card"])
        self.stats_body.pack(fill=tk.X, padx=14, pady=14)
        self.stat_widgets = {}
        for key in ["enterprise_stats_employees", "enterprise_stats_admins", "enterprise_stats_notices", "enterprise_stats_sync"]:
            box = tk.Frame(self.stats_body, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 10))
            value = tk.Label(box, text="0", font=("Microsoft YaHei UI", 20, "bold"), fg=self.colors["primary"], bg=self.colors["card_soft"])
            value.pack(anchor="w", padx=14, pady=(10, 0))
            label = tk.Label(box, text=self.app.t(key), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["card_soft"])
            label.pack(anchor="w", padx=14, pady=(0, 12))
            self.stat_widgets[key] = {"value": value, "label": label}

    def _build_goals_area(self):
        self.goals_title, self.goals_hint = self._title(self.goals_card, "goal_section", "goal_section_hint")
        body = tk.Frame(self.goals_card, bg=self.colors["card"])
        body.pack(fill=tk.BOTH, expand=True, padx=14, pady=(0, 14))

        summary = tk.Frame(body, bg=self.colors["card"])
        summary.pack(fill=tk.X, pady=(0, 12))
        self.goal_summary_boxes = {}
        for key in ("daily", "monthly", "yearly"):
            box = tk.Frame(summary, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 8))
            value = tk.Label(box, text="0%", font=("Microsoft YaHei UI", 16, "bold"), fg=self.colors["primary"], bg=self.colors["card_soft"])
            value.pack(anchor="w", padx=12, pady=(10, 0))
            label = tk.Label(box, text=self.app.t(f"goal_{key}"), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["card_soft"])
            label.pack(anchor="w", padx=12, pady=(0, 8))
            count = tk.Label(box, text="0", font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_light"], bg=self.colors["card_soft"])
            count.pack(anchor="w", padx=12, pady=(0, 10))
            self.goal_summary_boxes[key] = {"box": box, "value": value, "label": label, "count": count}

        self.goal_motivation_card = tk.Frame(body, bg=self.colors["primary_light"], highlightthickness=1, highlightbackground=self.colors["border"])
        self.goal_motivation_card.pack(fill=tk.X, pady=(0, 12))
        left_m = tk.Frame(self.goal_motivation_card, bg=self.colors["primary_light"])
        left_m.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=14, pady=12)
        self.goal_motivation_title = tk.Label(left_m, text=self.app.t("goal_motivation_title"), font=("Microsoft YaHei UI", 12, "bold"), fg=self.colors["primary"], bg=self.colors["primary_light"])
        self.goal_motivation_title.pack(anchor="w")
        self.goal_motivation_text = tk.Label(left_m, text=self.app.t("goal_motivation_default"), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["primary_light"], wraplength=460, justify=tk.LEFT)
        self.goal_motivation_text.pack(anchor="w", pady=(4, 0))
        self.goal_visual_canvas = tk.Canvas(self.goal_motivation_card, width=190, height=82, bg=self.colors["primary_light"], highlightthickness=0)
        self.goal_visual_canvas.pack(side=tk.RIGHT, padx=14, pady=10)

        form = tk.Frame(body, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
        form.pack(fill=tk.X, pady=(0, 12))
        grid = tk.Frame(form, bg=self.colors["card_soft"])
        grid.pack(fill=tk.X, padx=14, pady=12)
        self.goal_name_label = self._form_label(grid, "goal_name", 0, 0)
        self.goal_name_entry = self._form_entry(grid, 0, 1)
        self.goal_target_label = self._form_label(grid, "goal_target", 0, 2)
        self.goal_target_entry = self._form_entry(grid, 0, 3)
        self.goal_progress_label = self._form_label(grid, "goal_progress", 1, 0)
        self.goal_progress_entry = self._form_entry(grid, 1, 1)
        self.goal_period_label = self._form_label(grid, "goal_period", 1, 2)
        period_wrap = tk.Frame(grid, bg=self.colors["card_soft"])
        period_wrap.grid(row=1, column=3, sticky="w", pady=5)
        self.goal_period_var = tk.StringVar(value="monthly")
        self.goal_daily_radio = tk.Radiobutton(period_wrap, text=self.app.t("goal_daily"), variable=self.goal_period_var, value="daily", bg=self.colors["card_soft"], activebackground=self.colors["card_soft"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 9))
        self.goal_daily_radio.pack(side=tk.LEFT)
        self.goal_monthly_radio = tk.Radiobutton(period_wrap, text=self.app.t("goal_monthly"), variable=self.goal_period_var, value="monthly", bg=self.colors["card_soft"], activebackground=self.colors["card_soft"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 9))
        self.goal_monthly_radio.pack(side=tk.LEFT, padx=8)
        self.goal_yearly_radio = tk.Radiobutton(period_wrap, text=self.app.t("goal_yearly"), variable=self.goal_period_var, value="yearly", bg=self.colors["card_soft"], activebackground=self.colors["card_soft"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 9))
        self.goal_yearly_radio.pack(side=tk.LEFT)
        for col in [1, 3]:
            grid.grid_columnconfigure(col, weight=1)

        actions = tk.Frame(form, bg=self.colors["card_soft"])
        actions.pack(fill=tk.X, padx=14, pady=(0, 12))
        self.goal_add_btn = create_button(actions, self.app.t("goal_add"), self.add_goal, self.colors, filled=True)
        self.goal_add_btn.pack(side=tk.LEFT)
        self.goal_update_btn = create_button(actions, self.app.t("goal_update"), self.update_goal, self.colors)
        self.goal_update_btn.pack(side=tk.LEFT, padx=8)
        self.goal_delete_btn = create_button(actions, self.app.t("goal_delete"), self.delete_goal, self.colors)
        self.goal_delete_btn.pack(side=tk.LEFT)
        self.goal_clear_btn = create_button(actions, self.app.t("goal_clear"), self.clear_goal_form, self.colors)
        self.goal_clear_btn.pack(side=tk.RIGHT)

        self.goal_list_title = tk.Label(body, text=self.app.t("goal_list"), font=("Microsoft YaHei UI", 12, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.goal_list_title.pack(anchor="w", pady=(0, 8))
        self.goal_canvas = tk.Canvas(body, bg=self.colors["card"], highlightthickness=0, height=250)
        self.goal_inner = tk.Frame(self.goal_canvas, bg=self.colors["card"])
        self.goal_canvas.pack(fill=tk.BOTH, expand=True)
        self.goal_canvas_window = self.goal_canvas.create_window((0, 0), window=self.goal_inner, anchor="nw")
        self.goal_inner.bind("<Configure>", lambda e: self.goal_canvas.configure(scrollregion=self.goal_canvas.bbox("all")))
        self.goal_canvas.bind("<Configure>", lambda e: self.goal_canvas.itemconfig(self.goal_canvas_window, width=max(e.width - 4, 260)))
        self.goal_list = self.goal_inner

    def _build_employee_area(self):
        self.employee_title, _ = self._title(self.employee_card, "employee_section")

        body = tk.Frame(self.employee_card, bg=self.colors["card"])
        body.pack(fill=tk.BOTH, expand=True, padx=14, pady=(0, 14))

        form = tk.Frame(body, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
        form.pack(fill=tk.X, pady=(0, 12))

        grid = tk.Frame(form, bg=self.colors["card_soft"])
        grid.pack(fill=tk.X, padx=14, pady=12)

        self.name_label = self._form_label(grid, "employee_name", 0, 0)
        self.name_entry = self._form_entry(grid, 0, 1)
        self.position_label = self._form_label(grid, "employee_position", 0, 2)
        self.position_entry = self._form_entry(grid, 0, 3)

        self.dept_label = self._form_label(grid, "employee_department", 1, 0)
        self.dept_entry = self._form_entry(grid, 1, 1)
        self.email_label = self._form_label(grid, "employee_email", 1, 2)
        self.email_entry = self._form_entry(grid, 1, 3)

        self.is_admin_var = tk.BooleanVar(value=False)
        self.admin_check = tk.Checkbutton(grid, text=self.app.t("employee_admin"), variable=self.is_admin_var, bg=self.colors["card_soft"], activebackground=self.colors["card_soft"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 10))
        self.admin_check.grid(row=2, column=0, sticky="w", pady=(10, 0))

        self.status_var = tk.StringVar(value="active")
        self.active_radio = tk.Radiobutton(grid, text=self.app.t("employee_active"), variable=self.status_var, value="active", bg=self.colors["card_soft"], activebackground=self.colors["card_soft"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 10))
        self.active_radio.grid(row=2, column=1, sticky="w", pady=(10, 0))
        self.inactive_radio = tk.Radiobutton(grid, text=self.app.t("employee_inactive"), variable=self.status_var, value="inactive", bg=self.colors["card_soft"], activebackground=self.colors["card_soft"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 10))
        self.inactive_radio.grid(row=2, column=2, sticky="w", pady=(10, 0))

        for col in [1, 3]:
            grid.grid_columnconfigure(col, weight=1)

        actions = tk.Frame(form, bg=self.colors["card_soft"])
        actions.pack(fill=tk.X, padx=14, pady=(0, 12))
        self.add_btn = create_button(actions, self.app.t("employee_add"), self.add_employee, self.colors, filled=True)
        self.add_btn.pack(side=tk.LEFT)
        self.update_btn = create_button(actions, self.app.t("employee_update"), self.update_employee, self.colors)
        self.update_btn.pack(side=tk.LEFT, padx=8)
        self.delete_btn = create_button(actions, self.app.t("employee_delete"), self.delete_employee, self.colors)
        self.delete_btn.pack(side=tk.LEFT)
        self.clear_btn = create_button(actions, self.app.t("employee_clear"), self.clear_form, self.colors)
        self.clear_btn.pack(side=tk.RIGHT)

        self.employee_list_title = tk.Label(body, text=self.app.t("employee_list"), font=("Microsoft YaHei UI", 12, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.employee_list_title.pack(anchor="w", pady=(0, 8))
        self.employee_canvas = tk.Canvas(body, bg=self.colors["card"], highlightthickness=0)
        self.employee_inner = tk.Frame(self.employee_canvas, bg=self.colors["card"])
        self.employee_canvas.pack(fill=tk.BOTH, expand=True)
        self.employee_canvas_window = self.employee_canvas.create_window((0, 0), window=self.employee_inner, anchor="nw")
        self.employee_inner.bind("<Configure>", lambda e: self.employee_canvas.configure(scrollregion=self.employee_canvas.bbox("all")))
        self.employee_canvas.bind("<Configure>", lambda e: self.employee_canvas.itemconfig(self.employee_canvas_window, width=max(e.width - 4, 260)))
        self.employee_list = self.employee_inner

    def _form_label(self, parent, key, row, col):
        label = tk.Label(parent, text=self.app.t(key), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card_soft"])
        label.grid(row=row, column=col, sticky="w", padx=(0, 8), pady=5)
        return label

    def _form_entry(self, parent, row, col):
        entry = tk.Entry(parent, font=("Microsoft YaHei UI", 10), relief=tk.FLAT, bd=0, bg=self.colors["card"], fg=self.colors["text"])
        entry.grid(row=row, column=col, sticky="ew", padx=(0, 16), pady=5, ipady=7)
        return entry

    def _goal_completion(self, goal):
        try:
            target = float(goal.get("target") or 0)
            progress = float(goal.get("progress") or 0)
        except Exception:
            return 0.0
        if target <= 0:
            return 0.0
        return max(0.0, min(100.0, (progress / target) * 100.0))

    def _goal_period_label(self, period):
        return self.app.t(f"goal_{period}") if period in ("daily", "monthly", "yearly") else period

    def _goal_motivation_line(self, avg, total):
        if total <= 0:
            return self.app.t("goal_motivation_empty")
        if avg >= 100:
            return self.app.t("goal_motivation_done")
        if avg >= 70:
            return self.app.t("goal_motivation_good")
        if avg >= 35:
            return self.app.t("goal_motivation_mid")
        return self.app.t("goal_motivation_start")

    def _render_goal_visual(self, avg, total):
        canvas = getattr(self, "goal_visual_canvas", None)
        if not canvas:
            return
        canvas.delete("all")
        w, h = 190, 82
        colors = [self.colors["primary"], self.colors["success"], self.colors["warning"]]
        values = [max(8, avg), max(8, min(100, total * 14)), 100]
        x = 16
        for idx, val in enumerate(values):
            bh = int(52 * min(val, 100) / 100)
            canvas.create_rectangle(x, h - 16 - bh, x + 30, h - 16, fill=colors[idx % len(colors)], outline="")
            canvas.create_rectangle(x, h - 16 - bh, x + 30, h - 16 - bh + 3, fill="#ffffff", outline="")
            x += 46
        canvas.create_text(w - 18, 22, text=f"{avg:.0f}%", fill=self.colors["primary"], font=("Microsoft YaHei UI", 15, "bold"), anchor="e")
        canvas.create_text(w - 18, 48, text=self.app.t("goal_visual_label"), fill=self.colors["text_secondary"], font=("Microsoft YaHei UI", 8), anchor="e")

    def clear_goal_form(self):
        self.selected_goal_id = None
        for entry in (self.goal_name_entry, self.goal_target_entry, self.goal_progress_entry):
            entry.delete(0, tk.END)
        self.goal_period_var.set("monthly")
        self._render_goals()

    def select_goal(self, goal_id):
        for goal in self.app.enterprise.get("goals", []):
            if goal.get("id") == goal_id:
                self.selected_goal_id = goal_id
                self.goal_name_entry.delete(0, tk.END)
                self.goal_name_entry.insert(0, goal.get("name", ""))
                self.goal_target_entry.delete(0, tk.END)
                self.goal_target_entry.insert(0, str(goal.get("target", "")))
                self.goal_progress_entry.delete(0, tk.END)
                self.goal_progress_entry.insert(0, str(goal.get("progress", "")))
                self.goal_period_var.set(goal.get("period", "monthly"))
                self._render_goals()
                return

    def _parse_goal_form(self):
        name = self.goal_name_entry.get().strip()
        if not name:
            messagebox.showwarning(self.app.t("warning_title"), self.app.t("goal_required"))
            return None
        try:
            target = float(self.goal_target_entry.get().strip() or 0)
            progress = float(self.goal_progress_entry.get().strip() or 0)
        except Exception:
            messagebox.showwarning(self.app.t("warning_title"), self.app.t("goal_number_hint"))
            return None
        if target <= 0:
            messagebox.showwarning(self.app.t("warning_title"), self.app.t("goal_target_required"))
            return None
        return {"name": name, "target": target, "progress": progress, "period": self.goal_period_var.get()}

    def add_goal(self):
        if not self.app.require_admin() or not self.require_company():
            return
        payload = self._parse_goal_form()
        if not payload:
            return
        payload["id"] = f"goal-{int(time.time() * 1000)}"
        self.app.enterprise.setdefault("goals", []).append(payload)
        self._save_and_refresh()
        self.select_goal(payload["id"])

    def update_goal(self):
        if not self.app.require_admin() or not self.require_company():
            return
        if not self.selected_goal_id:
            self.add_goal()
            return
        payload = self._parse_goal_form()
        if not payload:
            return
        for goal in self.app.enterprise.get("goals", []):
            if goal.get("id") == self.selected_goal_id:
                goal.update(payload)
                break
        self._save_and_refresh()

    def delete_goal(self):
        if not self.app.require_admin() or not self.require_company():
            return
        if not self.selected_goal_id:
            return
        if not messagebox.askyesno(self.app.t("confirm_title"), self.app.t("goal_delete_confirm")):
            return
        self.app.enterprise["goals"] = [g for g in self.app.enterprise.get("goals", []) if g.get("id") != self.selected_goal_id]
        self.clear_goal_form()
        self._save_and_refresh()

    def _render_goals(self):
        for child in self.goal_list.winfo_children():
            child.destroy()
        if not self.company_created():
            show_empty(self.goal_list, self.app.t("company_required_hint"), self.colors)
            return
        goals = self.app.enterprise.get("goals", [])
        grouped = {"daily": [], "monthly": [], "yearly": []}
        for goal in goals:
            grouped.setdefault(goal.get("period", "monthly"), []).append(goal)
        for period, widgets in self.goal_summary_boxes.items():
            data = grouped.get(period, [])
            avg = (sum(self._goal_completion(g) for g in data) / len(data)) if data else 0
            widgets["value"].config(text=f"{avg:.0f}%")
            widgets["label"].config(text=self.app.t(f"goal_{period}"))
            widgets["count"].config(text=self.app.t("goal_summary_count").format(count=len(data)))
        overall_avg = (sum(self._goal_completion(g) for g in goals) / len(goals)) if goals else 0
        if hasattr(self, "goal_motivation_title"):
            self.goal_motivation_title.config(text=self.app.t("goal_motivation_title"))
            self.goal_motivation_text.config(text=self._goal_motivation_line(overall_avg, len(goals)))
            self._render_goal_visual(overall_avg, len(goals))
        if not goals:
            show_empty(self.goal_list, self.app.t("goal_empty"), self.colors)
            return
        for goal in goals:
            completion = self._goal_completion(goal)
            active = goal.get("id") == self.selected_goal_id
            bg = self.colors["primary_light"] if active else self.colors["card_soft"]
            row = tk.Frame(self.goal_list, bg=bg, highlightthickness=1, highlightbackground=self.colors["border"], cursor="hand2")
            row.pack(fill=tk.X, pady=5)
            top = tk.Frame(row, bg=bg)
            top.pack(fill=tk.X, padx=12, pady=(10, 4))
            tk.Label(top, text=goal.get("name", ""), font=("Microsoft YaHei UI", 11, "bold"), fg=self.colors["text"], bg=bg).pack(side=tk.LEFT)
            tk.Label(top, text=self._goal_period_label(goal.get("period", "monthly")), font=("Microsoft YaHei UI", 8, "bold"), fg=self.colors["primary"], bg=self.colors["card"], padx=8, pady=2).pack(side=tk.RIGHT)
            mid = tk.Frame(row, bg=bg)
            mid.pack(fill=tk.X, padx=12)
            tk.Label(mid, text=f"{goal.get('progress', 0):g} / {goal.get('target', 0):g}", font=("Microsoft YaHei UI", 10), fg=self.colors["text_secondary"], bg=bg).pack(side=tk.LEFT)
            status_key = "goal_status_done" if completion >= 100 else ("goal_status_on_track" if completion >= 60 else "goal_status_focus")
            tk.Label(mid, text=self.app.t(status_key), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["success" if completion >= 100 else ("primary" if completion >= 60 else "warning")], bg=bg).pack(side=tk.RIGHT)
            canvas = tk.Canvas(row, height=12, bg=bg, highlightthickness=0)
            canvas.pack(fill=tk.X, padx=12, pady=(8, 2))
            canvas.create_rectangle(0, 1, 300, 11, fill=self.colors["card"], outline=self.colors["border"])
            fillw = int(300 * min(completion, 100) / 100)
            canvas.create_rectangle(0, 1, fillw, 11, fill=self.colors["success" if completion >= 100 else ("primary" if completion >= 60 else "warning")], outline="")
            tk.Label(row, text=f"{completion:.0f}%", font=("Microsoft YaHei UI", 16, "bold"), fg=self.colors["primary"], bg=bg).pack(anchor="e", padx=12, pady=(0, 10))
            row.bind("<Button-1>", lambda e, gid=goal.get("id"): self.select_goal(gid))
            for child in row.winfo_children():
                child.bind("<Button-1>", lambda e, gid=goal.get("id"): self.select_goal(gid))

    def _build_org_area(self):
        self.org_title, self.org_hint = self._title(self.org_card, "org_section", "org_section_hint")
        org_actions = tk.Frame(self.org_card, bg=self.colors["card"])
        org_actions.pack(fill=tk.X, padx=14, pady=(0, 8))
        self.org_popup_btn = create_button(org_actions, self.app.t("org_open_large"), self.open_org_popup, self.colors)
        self.org_popup_btn.pack(anchor="w")
        self.org_body = tk.Frame(self.org_card, bg=self.colors["card"])
        self.org_body.pack(fill=tk.BOTH, expand=True, padx=14, pady=(0, 14))
        self.org_canvas = tk.Canvas(self.org_body, bg=self.colors["card"], highlightthickness=0, height=190)
        self.org_inner = tk.Frame(self.org_canvas, bg=self.colors["card"])
        self.org_canvas.pack(fill=tk.BOTH, expand=True)
        self.org_window = self.org_canvas.create_window((0, 0), window=self.org_inner, anchor="nw")
        self.org_inner.bind("<Configure>", lambda e: self.org_canvas.configure(scrollregion=self.org_canvas.bbox("all")))
        self.org_canvas.bind("<Configure>", lambda e: self.org_canvas.itemconfig(self.org_window, width=max(e.width - 4, 260)))

    def _build_notice_area(self):
        self.notice_title, _ = self._title(self.notice_card, "notification_section")
        body = tk.Frame(self.notice_card, bg=self.colors["card"])
        body.pack(fill=tk.BOTH, expand=True, padx=14, pady=(0, 14))

        self.notice_title_label = tk.Label(body, text=self.app.t("notification_title"), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card"])
        self.notice_title_label.pack(anchor="w")
        self.notice_title_entry = tk.Entry(body, font=("Microsoft YaHei UI", 10), relief=tk.FLAT, bd=0, bg=self.colors["bg"], fg=self.colors["text"])
        self.notice_title_entry.pack(fill=tk.X, ipady=8, pady=(6, 10))

        self.notice_content_label = tk.Label(body, text=self.app.t("notification_content"), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card"])
        self.notice_content_label.pack(anchor="w")
        self.notice_content = scrolledtext.ScrolledText(body, height=5, font=("Microsoft YaHei UI", 10), relief=tk.FLAT, bd=0, bg=self.colors["bg"], fg=self.colors["text"], wrap=tk.WORD)
        self.notice_content.pack(fill=tk.X, pady=(6, 10))

        self.audience_label = tk.Label(body, text=self.app.t("notification_audience"), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text_secondary"], bg=self.colors["card"])
        self.audience_label.pack(anchor="w")
        self.audience_var = tk.StringVar(value="all")
        audience = tk.Frame(body, bg=self.colors["card"])
        audience.pack(fill=tk.X, pady=(6, 10))
        self.all_radio = tk.Radiobutton(audience, text=self.app.t("notify_all"), variable=self.audience_var, value="all", bg=self.colors["card"], activebackground=self.colors["card"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 9))
        self.all_radio.pack(side=tk.LEFT)
        self.admin_radio = tk.Radiobutton(audience, text=self.app.t("notify_admins"), variable=self.audience_var, value="admins", bg=self.colors["card"], activebackground=self.colors["card"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 9))
        self.admin_radio.pack(side=tk.LEFT, padx=8)
        self.selected_radio = tk.Radiobutton(audience, text=self.app.t("notify_selected"), variable=self.audience_var, value="selected", bg=self.colors["card"], activebackground=self.colors["card"], selectcolor=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 9))
        self.selected_radio.pack(side=tk.LEFT)

        self.send_btn = create_button(body, self.app.t("notification_send"), self.send_notification, self.colors, filled=True)
        self.send_btn.pack(anchor="w", pady=(0, 12))

        sync_box = tk.Frame(body, bg=self.colors["primary_light"], highlightthickness=1, highlightbackground=self.colors["border"])
        sync_box.pack(fill=tk.X, pady=(0, 12))
        self.sync_title = tk.Label(sync_box, text=self.app.t("sync_section"), font=("Microsoft YaHei UI", 12, "bold"), fg=self.colors["primary"], bg=self.colors["primary_light"])
        self.sync_title.pack(anchor="w", padx=12, pady=(10, 2))
        self.sync_desc = tk.Label(sync_box, text=self.app.t("sync_desc"), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["primary_light"], wraplength=320, justify=tk.LEFT)
        self.sync_desc.pack(anchor="w", padx=12, pady=(0, 8))
        self.sync_last_label = tk.Label(sync_box, text="", font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text"], bg=self.colors["primary_light"])
        self.sync_last_label.pack(anchor="w", padx=12, pady=(0, 8))
        self.sync_btn = create_button(sync_box, self.app.t("sync_now"), self.sync_now, self.colors, filled=True)
        self.sync_btn.pack(anchor="w", padx=12, pady=(0, 12))

        self.history_title = tk.Label(body, text=self.app.t("notification_history"), font=("Microsoft YaHei UI", 12, "bold"), fg=self.colors["text"], bg=self.colors["card"])
        self.history_title.pack(anchor="w", pady=(4, 8))
        self.history_canvas = tk.Canvas(body, bg=self.colors["card"], highlightthickness=0)
        self.history_inner = tk.Frame(self.history_canvas, bg=self.colors["card"])
        self.history_canvas.pack(fill=tk.BOTH, expand=True)
        self.history_canvas_window = self.history_canvas.create_window((0, 0), window=self.history_inner, anchor="nw")
        self.history_inner.bind("<Configure>", lambda e: self.history_canvas.configure(scrollregion=self.history_canvas.bbox("all")))
        self.history_canvas.bind("<Configure>", lambda e: self.history_canvas.itemconfig(self.history_canvas_window, width=max(e.width - 4, 260)))
        self.history_list = self.history_inner

    def company_created(self):
        name = self.app.enterprise.get("company_name", "").strip()
        return bool(self.app.enterprise.get("company_created")) and bool(name)

    def user_enterprise_joined(self):
        # Admin who created the company is always considered joined.
        return bool(self.app.user_settings.get("enterprise_joined")) or self.app.is_admin()

    def enterprise_access_ready(self):
        return self.company_created() and self.user_enterprise_joined()

    def require_company(self):
        if self.company_created():
            return True
        messagebox.showwarning(self.app.t("company_required_title"), self.app.t("company_required_hint"))
        self.app.set_status("company_required_title")
        return False

    def _refresh_permissions(self):
        admin = self.app.is_admin()
        created = self.company_created()
        access_ready = self.enterprise_access_ready()
        restricted = []
        for name in ("add_btn", "update_btn", "delete_btn", "send_btn", "sync_btn", "goal_add_btn", "goal_update_btn", "goal_delete_btn"):
            if hasattr(self, name):
                restricted.append(getattr(self, name))
        for btn in restricted:
            try:
                btn.config(state=tk.NORMAL if (admin and created and access_ready) else tk.DISABLED)
            except Exception:
                pass
        if hasattr(self, "company_save_btn"):
            try:
                self.company_save_btn.config(state=tk.NORMAL if admin else tk.DISABLED)
            except Exception:
                pass
        if hasattr(self, "copy_invite_btn"):
            try:
                self.copy_invite_btn.config(state=tk.NORMAL if (admin and created) else tk.DISABLED)
            except Exception:
                pass
        if hasattr(self, "join_company_btn"):
            try:
                self.join_company_btn.config(state=tk.NORMAL if created else tk.DISABLED)
            except Exception:
                pass

    def _build_crm_area(self):
        self.crm_title, self.crm_hint = self._title(self.crm_card, "crm_section", "crm_section_hint")
        body = tk.Frame(self.crm_card, bg=self.colors["card"])
        body.pack(fill=tk.BOTH, expand=True, padx=18, pady=(0, 18))

        top = tk.Frame(body, bg=self.colors["card"])
        top.pack(fill=tk.X)
        form = tk.Frame(top, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
        form.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=(0, 12))
        tk.Label(form, text=self.app.t("crm_quick_ticket"), bg=self.colors["card_soft"], fg=self.colors["text"], font=("Microsoft YaHei UI", 12, "bold")).pack(anchor="w", padx=14, pady=(12, 8))

        def field(parent, key):
            tk.Label(parent, text=self.app.t(key), bg=self.colors["card_soft"], fg=self.colors["text_secondary"], font=("Microsoft YaHei UI", 9, "bold")).pack(anchor="w", padx=14, pady=(6, 2))
            entry = tk.Entry(parent, relief=tk.FLAT, bd=0, bg=self.colors["card"], fg=self.colors["text"], insertbackground=self.colors["text"], font=("Microsoft YaHei UI", 10))
            entry.pack(fill=tk.X, padx=14, ipady=7)
            return entry

        self.crm_customer_entry = field(form, "crm_customer_name")
        self.crm_contact_entry = field(form, "crm_contact_info")
        self.crm_issue_entry = field(form, "crm_issue_title")
        row = tk.Frame(form, bg=self.colors["card_soft"])
        row.pack(fill=tk.X, padx=14, pady=(10, 12))
        self.crm_priority_var = tk.StringVar(value="normal")
        self.crm_stage_var = tk.StringVar(value="open")
        tk.Label(row, text=self.app.t("crm_priority"), bg=self.colors["card_soft"], fg=self.colors["text_secondary"], font=("Microsoft YaHei UI", 9, "bold")).pack(side=tk.LEFT)
        tk.OptionMenu(row, self.crm_priority_var, "low", "normal", "high").pack(side=tk.LEFT, padx=(8, 16))
        tk.Label(row, text=self.app.t("crm_stage"), bg=self.colors["card_soft"], fg=self.colors["text_secondary"], font=("Microsoft YaHei UI", 9, "bold")).pack(side=tk.LEFT)
        tk.OptionMenu(row, self.crm_stage_var, "open", "following", "resolved").pack(side=tk.LEFT, padx=(8, 0))
        btn_row = tk.Frame(form, bg=self.colors["card_soft"])
        btn_row.pack(fill=tk.X, padx=14, pady=(0, 14))
        self.crm_add_btn = create_button(btn_row, self.app.t("crm_add_ticket"), self.add_crm_ticket, self.colors, filled=True)
        self.crm_add_btn.pack(side=tk.LEFT)
        self.crm_clear_btn = create_button(btn_row, self.app.t("goal_clear"), self.clear_crm_form, self.colors)
        self.crm_clear_btn.pack(side=tk.LEFT, padx=(8, 0))

        stat = tk.Frame(top, bg=self.colors["card"])
        stat.pack(side=tk.RIGHT, fill=tk.Y)
        self.crm_stats = []
        for _ in range(3):
            box = tk.Frame(stat, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            box.pack(fill=tk.X, pady=(0, 8))
            value = tk.Label(box, text="0", bg=self.colors["card_soft"], fg=self.colors["primary"], font=("Microsoft YaHei UI", 16, "bold"), width=8)
            value.pack(anchor="w", padx=12, pady=(8, 0))
            label = tk.Label(box, text="", bg=self.colors["card_soft"], fg=self.colors["text_secondary"], font=("Microsoft YaHei UI", 9))
            label.pack(anchor="w", padx=12, pady=(2, 8))
            self.crm_stats.append((value, label))

        self.crm_list_title = tk.Label(body, text=self.app.t("crm_ticket_list"), bg=self.colors["card"], fg=self.colors["text"], font=("Microsoft YaHei UI", 12, "bold"))
        self.crm_list_title.pack(anchor="w", pady=(14, 8))
        self.crm_list = tk.Frame(body, bg=self.colors["card"])
        self.crm_list.pack(fill=tk.BOTH, expand=True)

    def clear_crm_form(self):
        for entry in [self.crm_customer_entry, self.crm_contact_entry, self.crm_issue_entry]:
            entry.delete(0, tk.END)
        self.crm_priority_var.set("normal")
        self.crm_stage_var.set("open")

    def add_crm_ticket(self):
        if not self.app.require_admin():
            return
        if not self.require_company():
            return
        customer_name = self.crm_customer_entry.get().strip()
        issue = self.crm_issue_entry.get().strip()
        if not customer_name or not issue:
            messagebox.showwarning(self.app.t("warning_title") if "warning_title" in self.app.lang else self.app.t("confirm_title"), self.app.t("crm_required"))
            return
        now = datetime.now().strftime("%Y-%m-%d %H:%M")
        customers = self.app.crm.setdefault("customers", [])
        existing = next((c for c in customers if str(c.get("name", "")).strip().lower() == customer_name.lower()), None)
        if existing is None:
            existing = {
                "id": f"cust-{int(time.time() * 1000)}",
                "puid": self.app._new_puid("CPU") if hasattr(self.app, "_new_puid") else f"CPU-{int(time.time())}",
                "name": customer_name,
                "contact": self.crm_contact_entry.get().strip(),
                "stage": "new",
                "created_at": now,
                "updated_at": now,
            }
            customers.append(existing)
        else:
            existing["contact"] = self.crm_contact_entry.get().strip() or existing.get("contact", "")
            existing["updated_at"] = now
        ticket = {
            "id": f"ticket-{int(time.time() * 1000)}",
            "customer_id": existing.get("id"),
            "customer_puid": existing.get("puid", ""),
            "workspace_puid": getattr(self.app, "current_workspace_puid", lambda: "")(),
            "customer_name": customer_name,
            "contact": self.crm_contact_entry.get().strip(),
            "issue": issue,
            "priority": self.crm_priority_var.get(),
            "stage": self.crm_stage_var.get(),
            "created_at": now,
            "updated_at": now,
            "owner": self.app.user_settings.get("username", ""),
            "owner_puid": getattr(self.app, "current_puid", lambda: "")(),
        }
        self.app.crm.setdefault("tickets", []).append(ticket)
        self.app.crm.setdefault("activities", []).append({
            "id": f"act-{int(time.time() * 1000)}",
            "ticket_id": ticket["id"],
            "customer_id": existing.get("id"),
            "type": "create_ticket",
            "note": issue,
            "created_at": now,
        })
        save_crm(self.app.crm)
        try:
            self.app.sync_queue, _ = enqueue_sync_event(self.app.sync_queue, "crm_ticket", "upsert", payload=ticket, user=self.app.user_settings.get("username", ""), local_id=ticket["id"])
        except Exception:
            pass
        self.clear_crm_form()
        self.app.set_status("status_saved")
        self.refresh()

    def update_crm_ticket_stage(self, ticket_id, stage):
        if not self.app.require_admin():
            return
        for ticket in self.app.crm.get("tickets", []):
            if ticket.get("id") == ticket_id:
                ticket["stage"] = stage
                ticket["updated_at"] = datetime.now().strftime("%Y-%m-%d %H:%M")
                break
        save_crm(self.app.crm)
        self.refresh()

    def _render_crm(self):
        if not hasattr(self, "crm_list"):
            return
        for child in self.crm_list.winfo_children():
            child.destroy()
        customers = self.app.crm.get("customers", []) if isinstance(getattr(self.app, "crm", None), dict) else []
        tickets = self.app.crm.get("tickets", []) if isinstance(getattr(self.app, "crm", None), dict) else []
        open_tickets = [t for t in tickets if t.get("stage") != "resolved"]
        resolved = [t for t in tickets if t.get("stage") == "resolved"]
        stat_data = [
            (len(customers), self.app.t("crm_stat_customers")),
            (len(open_tickets), self.app.t("crm_stat_open")),
            (len(resolved), self.app.t("crm_stat_resolved")),
        ]
        for (value, label), (num, key_text) in zip(self.crm_stats, stat_data):
            value.config(text=str(num))
            label.config(text=key_text)
        if not tickets:
            show_empty(self.crm_list, self.app.t("crm_empty"), self.colors)
            return
        visible = [t for t in reversed(tickets) if self.app.matches_search(t.get("customer_name"), t.get("issue"), t.get("contact"), t.get("stage"))][:12]
        for ticket in visible:
            stage = ticket.get("stage", "open")
            bg = self.colors["success_light"] if stage == "resolved" else (self.colors["warning_light"] if ticket.get("priority") == "high" else self.colors["card_soft"])
            row = tk.Frame(self.crm_list, bg=bg, highlightthickness=1, highlightbackground=self.colors["border"])
            row.pack(fill=tk.X, pady=4)
            top = tk.Frame(row, bg=bg)
            top.pack(fill=tk.X, padx=12, pady=(9, 0))
            display_name = ticket.get("customer_name", "")
            # Internal customer identifiers stay hidden from user-facing ticket rows.
            tk.Label(top, text=display_name, bg=bg, fg=self.colors["text"], font=("Microsoft YaHei UI", 10, "bold")).pack(side=tk.LEFT)
            tk.Label(top, text=f"{ticket.get('priority','normal')} · {stage}", bg=self.colors["card"], fg=self.colors["primary"], font=("Microsoft YaHei UI", 8, "bold"), padx=8, pady=2).pack(side=tk.LEFT, padx=8)
            detail_text = f"{ticket.get('issue','')}\n{ticket.get('contact','')} · {ticket.get('created_at','')}"
            tk.Label(row, text=detail_text, bg=bg, fg=self.colors["text_secondary"], font=("Microsoft YaHei UI", 8), justify=tk.LEFT, wraplength=680).pack(anchor="w", padx=12, pady=(4, 8))
            actions = tk.Frame(row, bg=bg)
            actions.pack(anchor="w", padx=12, pady=(0, 10))
            create_button(actions, self.app.t("crm_mark_following"), lambda tid=ticket.get("id"): self.update_crm_ticket_stage(tid, "following"), self.colors).pack(side=tk.LEFT)
            create_button(actions, self.app.t("crm_mark_resolved"), lambda tid=ticket.get("id"): self.update_crm_ticket_stage(tid, "resolved"), self.colors, filled=True).pack(side=tk.LEFT, padx=(8, 0))

    def refresh(self):
        self._refresh_permissions()
        if hasattr(self, "company_var"):
            self.company_var.set(self.app.enterprise.get("company_name", ""))
        if hasattr(self, "company_status"):
            self.company_status.config(
                text=self.app.t("company_created") if self.company_created() else self.app.t("company_not_created"),
                fg=self.colors["success"] if self.company_created() else self.colors["warning"],
            )
        if hasattr(self, "invite_status"):
            if self.company_created():
                code = self._ensure_invite_code()
                status = self.app.t("enterprise_access_status_member") if self.user_enterprise_joined() else self.app.t("enterprise_access_status_not_member")
                self.invite_status.config(text=f"{self.app.t('enterprise_invite_current')}: {code} · {status}", fg=self.colors["success"] if self.user_enterprise_joined() else self.colors["warning"])
            else:
                self.invite_status.config(text=self.app.t("enterprise_access_status_empty"), fg=self.colors["text_secondary"])
        self._refresh_workspace_summary()
        self._render_stats()
        self._render_goals()
        self._render_org()
        self._render_employees()
        self._render_history()
        self._render_crm()
        self._update_sync_label()

    def update_language(self):
        for module, key in [
            ("overview", "enterprise_tab_overview"),
            ("goals", "enterprise_tab_goals"),
            ("employees", "enterprise_tab_employees"),
            ("org", "enterprise_tab_org"),
            ("notices", "enterprise_tab_notices"),
            ("crm", "enterprise_tab_crm"),
        ]:
            if module in self.module_tabs:
                self.module_tabs[module].config(text=self.app.t(key))
        if hasattr(self, "summary_title"):
            self.summary_title.config(text=self.app.t("enterprise_overview_title"))
        if hasattr(self, "summary_hint"):
            self.summary_hint.config(text=self.app.t("enterprise_overview_hint"))
        if hasattr(self, "summary_primary_btn"):
            self.summary_primary_btn.config(text=self.app.t("enterprise_overview_open_notices"))
        if hasattr(self, "summary_secondary_btn"):
            self.summary_secondary_btn.config(text=self.app.t("enterprise_overview_open_goals"))
        self.company_title.config(text=self.app.t("company_section"))
        self.company_label.config(text=self.app.t("company_name"))
        self.company_save_btn.config(text=self.app.t("enterprise_create_workspace"))
        if hasattr(self, "access_title"):
            self.access_title.config(text=self.app.t("enterprise_access_title"))
        if hasattr(self, "access_hint"):
            self.access_hint.config(text=self.app.t("enterprise_access_hint"))
        if hasattr(self, "invite_code_label"):
            self.invite_code_label.config(text=self.app.t("enterprise_invite_code"))
        if hasattr(self, "join_company_btn"):
            self.join_company_btn.config(text=self.app.t("enterprise_join_workspace"))
        if hasattr(self, "copy_invite_btn"):
            self.copy_invite_btn.config(text=self.app.t("enterprise_copy_invite"))
        if hasattr(self, "company_status"):
            self.company_status.config(text=self.app.t("company_created") if self.company_created() else self.app.t("company_not_created"))
        self.goals_title.config(text=self.app.t("goal_section"))
        if hasattr(self, "goals_hint") and self.goals_hint:
            self.goals_hint.config(text=self.app.t("goal_section_hint"))
        self.goal_name_label.config(text=self.app.t("goal_name"))
        self.goal_period_label.config(text=self.app.t("goal_period"))
        self.goal_target_label.config(text=self.app.t("goal_target"))
        self.goal_progress_label.config(text=self.app.t("goal_progress"))
        self.goal_daily_radio.config(text=self.app.t("goal_daily"))
        self.goal_monthly_radio.config(text=self.app.t("goal_monthly"))
        self.goal_yearly_radio.config(text=self.app.t("goal_yearly"))
        self.goal_add_btn.config(text=self.app.t("goal_add"))
        self.goal_update_btn.config(text=self.app.t("goal_update"))
        self.goal_delete_btn.config(text=self.app.t("goal_delete"))
        self.goal_clear_btn.config(text=self.app.t("goal_clear"))
        self.goal_list_title.config(text=self.app.t("goal_list"))
        self.employee_title.config(text=self.app.t("employee_section"))
        self.name_label.config(text=self.app.t("employee_name"))
        self.position_label.config(text=self.app.t("employee_position"))
        self.dept_label.config(text=self.app.t("employee_department"))
        self.email_label.config(text=self.app.t("employee_email"))
        self.admin_check.config(text=self.app.t("employee_admin"))
        self.active_radio.config(text=self.app.t("employee_active"))
        self.inactive_radio.config(text=self.app.t("employee_inactive"))
        self.add_btn.config(text=self.app.t("employee_add"))
        self.update_btn.config(text=self.app.t("employee_update"))
        self.delete_btn.config(text=self.app.t("employee_delete"))
        self.clear_btn.config(text=self.app.t("employee_clear"))
        self.employee_list_title.config(text=self.app.t("employee_list"))

        if hasattr(self, "org_title"):
            self.org_title.config(text=self.app.t("org_section"))
        if hasattr(self, "org_hint") and self.org_hint:
            self.org_hint.config(text=self.app.t("org_section_hint"))
        if hasattr(self, "crm_title"):
            self.crm_title.config(text=self.app.t("crm_section"))
        if hasattr(self, "crm_hint") and self.crm_hint:
            self.crm_hint.config(text=self.app.t("crm_section_hint"))
        if hasattr(self, "crm_add_btn"):
            self.crm_add_btn.config(text=self.app.t("crm_add_ticket"))
        if hasattr(self, "crm_clear_btn"):
            self.crm_clear_btn.config(text=self.app.t("goal_clear"))
        if hasattr(self, "crm_list_title"):
            self.crm_list_title.config(text=self.app.t("crm_ticket_list"))
        self.notice_title.config(text=self.app.t("notification_section"))
        self.notice_title_label.config(text=self.app.t("notification_title"))
        self.notice_content_label.config(text=self.app.t("notification_content"))
        self.audience_label.config(text=self.app.t("notification_audience"))
        self.all_radio.config(text=self.app.t("notify_all"))
        self.admin_radio.config(text=self.app.t("notify_admins"))
        self.selected_radio.config(text=self.app.t("notify_selected"))
        self.send_btn.config(text=self.app.t("notification_send"))
        self.sync_title.config(text=self.app.t("sync_section"))
        self.sync_desc.config(text=self.app.t("sync_desc"))
        self.sync_btn.config(text=self.app.t("sync_now"))
        self.history_title.config(text=self.app.t("notification_history"))
        for key, widgets in self.stat_widgets.items():
            widgets["label"].config(text=self.app.t(key))
        self.refresh()

    def _render_stats(self):
        employees = self.app.enterprise.get("employees", [])
        notices = self.app.enterprise.get("notifications", [])
        admins = [emp for emp in employees if emp.get("is_admin")]
        self.stat_widgets["enterprise_stats_employees"]["value"].config(text=str(len(employees)))
        self.stat_widgets["enterprise_stats_admins"]["value"].config(text=str(len(admins)))
        self.stat_widgets["enterprise_stats_notices"]["value"].config(text=str(len(notices)))
        self.stat_widgets["enterprise_stats_sync"]["value"].config(text="✓" if self.app.enterprise.get("last_sync") else "—")

    def open_org_popup(self):
        if not self.company_created():
            messagebox.showwarning(self.app.t("company_required_title"), self.app.t("company_required_hint"))
            return
        win = tk.Toplevel(self.app.root)
        win.title(self.app.t("org_section"))
        win.configure(bg=self.colors["bg"])
        try:
            win.transient(self.app.root)
            center_window(win, self.app.root, 760, 680, min_width=620, min_height=520)
        except Exception:
            win.geometry("760x680")
        card = create_card(win, self.colors)
        card.pack(fill=tk.BOTH, expand=True, padx=18, pady=18)
        tk.Label(card, text=self.app.enterprise.get("company_name", self.app.t("org_section")), font=("Microsoft YaHei UI", 20, "bold"), bg=self.colors["card"], fg=self.colors["text"]).pack(anchor="w", padx=18, pady=(18, 6))
        tk.Label(card, text=self.app.t("org_section_hint"), font=("Microsoft YaHei UI", 10), bg=self.colors["card"], fg=self.colors["text_secondary"]).pack(anchor="w", padx=18, pady=(0, 12))
        canvas = tk.Canvas(card, bg=self.colors["card"], highlightthickness=0)
        inner = tk.Frame(canvas, bg=self.colors["card"])
        canvas.pack(fill=tk.BOTH, expand=True, padx=18, pady=(0, 18))
        canvas.create_window((0, 0), window=inner, anchor="nw")
        inner.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
        employees = [e for e in self.app.enterprise.get("employees", []) if e.get("status", "active") == "active"]
        departments = {}
        for emp in employees:
            dept = emp.get("department") or self.app.t("org_default_department")
            departments.setdefault(dept, []).append(emp)
        for dept, members in sorted(departments.items(), key=lambda x: x[0]):
            box = tk.Frame(inner, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            box.pack(fill=tk.X, pady=6)
            tk.Label(box, text=f"▥ {dept}  ·  {len(members)}", font=("Microsoft YaHei UI", 13, "bold"), bg=self.colors["card_soft"], fg=self.colors["primary"]).pack(anchor="w", padx=12, pady=(10, 4))
            for emp in members:
                badge = self.app.t("admin_badge") if emp.get("is_admin") else self.app.t("normal_staff")
                tk.Label(box, text=f"  • {emp.get('name','')}  |  {emp.get('position','')}  |  {badge}  |  {emp.get('email','')}", font=("Microsoft YaHei UI", 10), bg=self.colors["card_soft"], fg=self.colors["text"], anchor="w").pack(fill=tk.X, padx=12, pady=2)

    def _render_org(self):
        if not hasattr(self, "org_inner"):
            return
        for child in self.org_inner.winfo_children():
            child.destroy()
        if not self.company_created():
            show_empty(self.org_inner, self.app.t("company_required_hint"), self.colors)
            return
        employees = [e for e in self.app.enterprise.get("employees", []) if e.get("status", "active") == "active"]
        if not employees:
            show_empty(self.org_inner, self.app.t("org_empty"), self.colors)
            return
        departments = {}
        for emp in employees:
            dept = emp.get("department") or self.app.t("org_default_department")
            departments.setdefault(dept, []).append(emp)
        for dept, members in sorted(departments.items(), key=lambda x: x[0]):
            box = tk.Frame(self.org_inner, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            box.pack(fill=tk.X, pady=5)
            tk.Label(box, text=f"▥ {dept}", font=("Microsoft YaHei UI", 10, "bold"), fg=self.colors["primary"], bg=self.colors["card_soft"]).pack(anchor="w", padx=10, pady=(8, 2))
            names = []
            for emp in members:
                badge = self.app.t("admin_badge") if emp.get("is_admin") else self.app.t("normal_staff")
                names.append(f"{emp.get('name','')} · {emp.get('position','')} · {badge}")
            tk.Label(box, text="\n".join(names), font=("Microsoft YaHei UI", 9), fg=self.colors["text_secondary"], bg=self.colors["card_soft"], justify=tk.LEFT, wraplength=310).pack(anchor="w", padx=10, pady=(2, 9))

    def _render_employees(self):
        for child in self.employee_list.winfo_children():
            child.destroy()
        if not self.company_created():
            show_empty(self.employee_list, self.app.t("company_required_hint"), self.colors)
            return
        employees = [emp for emp in self.app.enterprise.get("employees", []) if self.app.matches_search(emp.get("name"), emp.get("position"), emp.get("department"), emp.get("email"))]
        if not employees:
            show_empty(self.employee_list, self.app.t("employee_list"), self.colors)
            return
        for emp in employees:
            bg = self.colors["primary_light"] if emp.get("id") == self.selected_employee_id else self.colors["card_soft"]
            row = tk.Frame(self.employee_list, bg=bg, highlightthickness=1, highlightbackground=self.colors["border"], cursor="hand2")
            row.pack(fill=tk.X, pady=4)
            top = tk.Frame(row, bg=bg)
            top.pack(fill=tk.X, padx=12, pady=(9, 0))
            name = emp.get("name", "")
            badge = self.app.t("admin_badge") if emp.get("is_admin") else self.app.t("normal_staff")
            tk.Label(top, text=name, font=("Microsoft YaHei UI", 10, "bold"), fg=self.colors["text"], bg=bg).pack(side=tk.LEFT)
            tk.Label(top, text=badge, font=("Microsoft YaHei UI", 8, "bold"), fg=self.colors["primary"] if emp.get("is_admin") else self.colors["text_secondary"], bg=self.colors["card"], padx=8, pady=2).pack(side=tk.LEFT, padx=8)
            status = self.app.t("employee_active") if emp.get("status") == "active" else self.app.t("employee_inactive")
            tk.Label(row, text=f"{emp.get('position','')} · {emp.get('department','')} · {status}\n{emp.get('email','')}", font=("Microsoft YaHei UI", 8), fg=self.colors["text_secondary"], bg=bg, justify=tk.LEFT).pack(anchor="w", padx=12, pady=(4, 10))
            row.bind("<Button-1>", lambda e, emp_id=emp.get("id"): self.select_employee(emp_id))
            for child in row.winfo_children():
                child.bind("<Button-1>", lambda e, emp_id=emp.get("id"): self.select_employee(emp_id))

    def _render_history(self):
        for child in self.history_list.winfo_children():
            child.destroy()
        if not self.company_created():
            show_empty(self.history_list, self.app.t("company_required_hint"), self.colors)
            return
        notices = self.app.enterprise.get("notifications", [])
        if not notices:
            show_empty(self.history_list, self.app.t("notification_history"), self.colors)
            return
        for notice in list(reversed(notices))[:6]:
            row = tk.Frame(self.history_list, bg=self.colors["card_soft"], highlightthickness=1, highlightbackground=self.colors["border"])
            row.pack(fill=tk.X, pady=4)
            tk.Label(row, text=notice.get("title", ""), font=("Microsoft YaHei UI", 9, "bold"), fg=self.colors["text"], bg=self.colors["card_soft"], wraplength=320, justify=tk.LEFT).pack(anchor="w", padx=10, pady=(8, 0))
            tk.Label(row, text=f"{notice.get('time', '')} · {notice.get('audience_label', '')}", font=("Microsoft YaHei UI", 8), fg=self.colors["text_secondary"], bg=self.colors["card_soft"]).pack(anchor="w", padx=10, pady=(2, 8))

    def _update_sync_label(self):
        last = self.app.enterprise.get("last_sync")
        text = f"{self.app.t('sync_last_time')}: {last if last else self.app.t('sync_never')}"
        self.sync_last_label.config(text=text)

    def select_employee(self, emp_id):
        emp = self._find_employee(emp_id)
        if not emp:
            return
        self.selected_employee_id = emp_id
        self.name_entry.delete(0, tk.END)
        self.name_entry.insert(0, emp.get("name", ""))
        self.position_entry.delete(0, tk.END)
        self.position_entry.insert(0, emp.get("position", ""))
        self.dept_entry.delete(0, tk.END)
        self.dept_entry.insert(0, emp.get("department", ""))
        self.email_entry.delete(0, tk.END)
        self.email_entry.insert(0, emp.get("email", ""))
        self.is_admin_var.set(bool(emp.get("is_admin")))
        self.status_var.set(emp.get("status", "active"))
        self._render_employees()

    def clear_form(self):
        self.selected_employee_id = None
        for entry in [self.name_entry, self.position_entry, self.dept_entry, self.email_entry]:
            entry.delete(0, tk.END)
        self.is_admin_var.set(False)
        self.status_var.set("active")
        self._render_employees()

    def add_employee(self):
        if not self.app.require_admin():
            return
        if not self.require_company():
            return
        name = self.name_entry.get().strip()
        if not name:
            messagebox.showwarning(self.app.t("warning_title") if "warning_title" in self.app.lang else self.app.t("confirm_title"), self.app.t("employee_required"))
            return
        emp = {
            "id": f"emp-{int(time.time() * 1000)}",
            "name": name,
            "position": self.position_entry.get().strip(),
            "department": self.dept_entry.get().strip(),
            "email": self.email_entry.get().strip(),
            "is_admin": self.is_admin_var.get(),
            "status": self.status_var.get(),
        }
        self.app.enterprise.setdefault("employees", []).append(emp)
        self._save_and_refresh()
        self.select_employee(emp["id"])

    def update_employee(self):
        if not self.app.require_admin():
            return
        if not self.require_company():
            return
        if not self.selected_employee_id:
            self.add_employee()
            return
        emp = self._find_employee(self.selected_employee_id)
        if not emp:
            return
        name = self.name_entry.get().strip()
        if not name:
            messagebox.showwarning(self.app.t("confirm_title"), self.app.t("employee_required"))
            return
        emp.update({
            "name": name,
            "position": self.position_entry.get().strip(),
            "department": self.dept_entry.get().strip(),
            "email": self.email_entry.get().strip(),
            "is_admin": self.is_admin_var.get(),
            "status": self.status_var.get(),
        })
        self._save_and_refresh()

    def delete_employee(self):
        if not self.app.require_admin():
            return
        if not self.require_company():
            return
        if not self.selected_employee_id:
            return
        if not messagebox.askyesno(self.app.t("confirm_title"), self.app.t("employee_delete_confirm")):
            return
        self.app.enterprise["employees"] = [emp for emp in self.app.enterprise.get("employees", []) if emp.get("id") != self.selected_employee_id]
        self.clear_form()
        self._save_and_refresh()

    def send_notification(self):
        if not self.app.require_admin():
            return
        if not self.require_company():
            return
        title = self.notice_title_entry.get().strip()
        content = self.notice_content.get("1.0", tk.END).strip()
        if not title or not content:
            messagebox.showwarning(self.app.t("confirm_title"), self.app.t("notification_required"))
            return

        audience = self.audience_var.get()
        audience_label = self._audience_label(audience)
        notice = {
            "id": f"notice-{int(time.time() * 1000)}",
            "title": title,
            "content": content,
            "audience": audience,
            "audience_label": audience_label,
            "time": datetime.now().strftime("%Y-%m-%d %H:%M"),
        }
        self.app.enterprise.setdefault("notifications", []).append(notice)
        save_enterprise(self.app.enterprise)

        try:
            desktop_notify(title=title, message=content[:180], timeout=8)
        except Exception:
            pass

        self.notice_title_entry.delete(0, tk.END)
        self.notice_content.delete("1.0", tk.END)
        self.app.set_status("notification_sent")
        self.refresh()
        messagebox.showinfo(self.app.t("success_title") if "success_title" in self.app.lang else self.app.t("confirm_title"), self.app.t("notification_sent"))

    def sync_now(self):
        if not self.app.require_admin():
            return
        if not self.require_company():
            return
        sync_dir = DATA_DIR / "sync_backup"
        sync_dir.mkdir(parents=True, exist_ok=True)
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        snapshot = {
            "synced_at": now,
            "enterprise": self.app.enterprise,
            "notes": self.app.notes,
            "todos": self.app.todos,
            "documents": self.app.documents,
            "settings": self.app.user_settings,
        }
        safe_time = datetime.now().strftime("%Y%m%d_%H%M%S")
        file_path = sync_dir / f"sync_snapshot_{safe_time}.json"
        with open(file_path, "w", encoding="utf-8") as f:
            json.dump(snapshot, f, ensure_ascii=False, indent=2)

        self.app.enterprise["last_sync"] = now
        save_enterprise(self.app.enterprise)
        self.app.set_status("sync_success")
        self.refresh()
        try:
            desktop_notify(title=self.app.t("sync_success"), message=str(file_path), timeout=6)
        except Exception:
            pass
        messagebox.showinfo(self.app.t("sync_success"), f"{self.app.t('sync_snapshot')}:\n{file_path}")

    def _audience_label(self, audience):
        if audience == "admins":
            return self.app.t("notify_admins")
        if audience == "selected":
            emp = self._find_employee(self.selected_employee_id)
            return emp.get("name") if emp else self.app.t("notify_selected")
        return self.app.t("notify_all")

    def _find_employee(self, emp_id):
        for emp in self.app.enterprise.get("employees", []):
            if emp.get("id") == emp_id:
                return emp
        return None

    def _save_and_refresh(self):
        save_enterprise(self.app.enterprise)
        self.app.set_status("status_saved")
        self.refresh()
