import { useCallback, useEffect, useState } from "react";
import {
  Plus,
  Search,
  SlidersHorizontal,
  UserPlus,
} from "lucide-react";

import OmsorgCard from "../../components/OmsorgCard";
import OmsorgButton from "../../components/ui/OmsorgButton";
import OmsorgBadge from "../../components/ui/OmsorgBadge";
import OmsorgPagination from "../../components/ui/OmsorgPagination";
import { useAuth } from "../../app/AuthContext";
import EmployeeDetailPanel from "./EmployeeDetailPanel";
import CreateEmployeeDialog from "./CreateEmployeeDialog";
import CreateUserAccountDialog from "./CreateUserAccountDialog";
import { useValueListItems } from "../../app/useValueListItems";

const PAGE_SIZE = 20;

function getInitials(firstName = "", lastName = "") {
  return `${firstName[0] ?? ""}${lastName[0] ?? ""}`.toUpperCase();
}

function fullName(employee) {
  return `${employee.firstName} ${employee.lastName}`.trim();
}

export default function EmployeesPage() {
  const { hasPermission } = useAuth();
  const { items: statusOptions } = useValueListItems("EmployeeStatus");
  const { items: employmentTypes } = useValueListItems("EmploymentType");
  const canCreate = hasPermission("Employees", "Create");
  const canViewAccounts = hasPermission("Users", "View");
  const canCreateAccounts = hasPermission("Users", "Create");

  const [employees, setEmployees] = useState([]);
  const [totalCount, setTotalCount] = useState(0);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [selectedEmployeeId, setSelectedEmployeeId] = useState(null);
  const [searchTerm, setSearchTerm] = useState("");
  const [debouncedSearch, setDebouncedSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [employmentTypeFilter, setEmploymentTypeFilter] = useState("");
  const [isFilterOpen, setIsFilterOpen] = useState(false);
  const [page, setPage] = useState(1);
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [employeeIdsWithAccount, setEmployeeIdsWithAccount] = useState(new Set());
  const [accountDialogEmployee, setAccountDialogEmployee] = useState(null);

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedSearch(searchTerm.trim()), 300);
    return () => clearTimeout(timer);
  }, [searchTerm]);

  useEffect(() => {
    setPage(1);
  }, [debouncedSearch, statusFilter, employmentTypeFilter]);

  const loadAccountStatus = useCallback(async () => {
    if (!canViewAccounts) return;
    const result = await window.omsorg.users.list();
    if (result.ok) {
      const ids = (result.data ?? [])
        .map((user) => user.employeeId)
        .filter((id) => id != null);
      setEmployeeIdsWithAccount(new Set(ids));
    }
  }, [canViewAccounts]);

  const loadEmployees = useCallback(async () => {
    setIsLoading(true);
    setError(null);

    const result = await window.omsorg.employees.list({
      search: debouncedSearch || undefined,
      status: statusFilter || undefined,
      employmentType: employmentTypeFilter || undefined,
      page,
      pageSize: PAGE_SIZE,
    });

    if (result.ok) {
      const data = result.data ?? { items: [], totalCount: 0 };
      setEmployees(data.items ?? []);
      setTotalCount(data.totalCount ?? 0);
      setSelectedEmployeeId((current) =>
        (data.items ?? []).some((employee) => employee.id === current)
          ? current
          : data.items?.[0]?.id ?? null
      );
    } else {
      setError("Mitarbeiter konnten nicht geladen werden.");
    }

    setIsLoading(false);
  }, [debouncedSearch, statusFilter, employmentTypeFilter, page]);

  useEffect(() => {
    loadEmployees();
  }, [loadEmployees]);

  useEffect(() => {
    loadAccountStatus();
  }, [loadAccountStatus]);

  // Mitarbeiter ohne Account zuerst (das sind die offenen Fälle) - nur die aktuell geladene Seite,
  // die Mitarbeiterliste selbst bleibt serverseitig paginiert.
  const sortedEmployees = canViewAccounts
    ? [...employees].sort((a, b) => {
        const aHasAccount = employeeIdsWithAccount.has(a.id) ? 1 : 0;
        const bHasAccount = employeeIdsWithAccount.has(b.id) ? 1 : 0;
        return aHasAccount - bHasAccount;
      })
    : employees;

  function handleAccountCreated() {
    setAccountDialogEmployee(null);
    loadAccountStatus();
  }

  const selectedEmployee = employees.find((employee) => employee.id === selectedEmployeeId) ?? null;
  const totalPages = Math.max(1, Math.ceil(totalCount / PAGE_SIZE));

  function handleCreated(createdEmployee) {
    setIsDialogOpen(false);
    loadEmployees();
    if (createdEmployee?.id) {
      setSelectedEmployeeId(createdEmployee.id);
    }
  }

  function handleUpdated() {
    loadEmployees();
  }

  return (
    <div className="employees-page">
      <div className="page-heading">
        <div>
          <p className="page-eyebrow">
            Personalverwaltung
          </p>

          <h1>Mitarbeiter</h1>

          <p className="page-description">
            Verwalte Personaldaten, Status, Verträge
            und Dokumente an einem Ort.
          </p>
        </div>

        {canCreate && (
          <OmsorgButton icon={Plus} onClick={() => setIsDialogOpen(true)}>
            Neuer Mitarbeiter
          </OmsorgButton>
        )}
      </div>

      <OmsorgCard>
        <div className="employees-toolbar">
          <div className="employees-search">
            <Search size={18} />

            <input
              type="search"
              value={searchTerm}
              onChange={(event) =>
                setSearchTerm(event.target.value)
              }
              placeholder="Mitarbeiter suchen..."
              aria-label="Mitarbeiter suchen"
            />
          </div>

          <OmsorgButton
            variant="secondary"
            icon={SlidersHorizontal}
            onClick={() => setIsFilterOpen((open) => !open)}
          >
            Filter
          </OmsorgButton>
        </div>

        {isFilterOpen && (
          <div className="employees-filter-panel">
            <label className="form-field">
              <span>Status</span>
              <select value={statusFilter} onChange={(event) => setStatusFilter(event.target.value)}>
                <option value="">Alle</option>
                {statusOptions.map((option) => (
                  <option key={option.id} value={option.value}>
                    {option.value}
                  </option>
                ))}
              </select>
            </label>

            <label className="form-field">
              <span>Beschäftigungsart</span>
              <select
                value={employmentTypeFilter}
                onChange={(event) => setEmploymentTypeFilter(event.target.value)}
              >
                <option value="">Alle</option>
                {employmentTypes.map((option) => (
                  <option key={option.id} value={option.value}>
                    {option.value}
                  </option>
                ))}
              </select>
            </label>
          </div>
        )}
      </OmsorgCard>

      {error && <p className="login-error">{error}</p>}
      {isLoading && <p>Lädt...</p>}

      {!isLoading && (
        <div className="employees-layout">
          <div className="employees-list">
            {sortedEmployees.map((employee) => {
              const isSelected = employee.id === selectedEmployeeId;
              const hasAccount = employeeIdsWithAccount.has(employee.id);

              return (
                <div key={employee.id} className="employee-row-wrapper">
                  <button
                    type="button"
                    className={
                      isSelected
                        ? "employee-list-button employee-list-button--active"
                        : "employee-list-button"
                    }
                    onClick={() =>
                      setSelectedEmployeeId(employee.id)
                    }
                  >
                    <OmsorgCard>
                      <div className="employee-row">
                        <div className="employee-avatar">
                          {getInitials(employee.firstName, employee.lastName)}
                        </div>

                        <div className="employee-main">
                          <strong>{fullName(employee)}</strong>
                        </div>

                        {canViewAccounts && (
                          <span
                            className={
                              hasAccount
                                ? "omsorg-badge omsorg-badge--success"
                                : "omsorg-badge omsorg-badge--neutral"
                            }
                          >
                            {hasAccount ? "Account vorhanden" : "Kein Account"}
                          </span>
                        )}

                        <div className="employee-status">
                          <OmsorgBadge
                            status={employee.status?.toLowerCase()}
                          />
                        </div>
                      </div>
                    </OmsorgCard>
                  </button>

                  {canCreateAccounts && !hasAccount && (
                    <OmsorgButton
                      variant="secondary"
                      icon={UserPlus}
                      onClick={(event) => {
                        event.stopPropagation();
                        setAccountDialogEmployee(employee);
                      }}
                    >
                      Account anlegen
                    </OmsorgButton>
                  )}
                </div>
              );
            })}

            {employees.length === 0 && (
              <OmsorgCard>
                <div className="employees-empty-state">
                  <strong>
                    Kein Mitarbeiter gefunden
                  </strong>

                  <span>
                    Prüfe den eingegebenen Suchbegriff oder die Filter.
                  </span>
                </div>
              </OmsorgCard>
            )}

            {employees.length > 0 && (
              <OmsorgPagination page={page} totalPages={totalPages} onPageChange={setPage} />
            )}
          </div>

          <EmployeeDetailPanel
            employee={selectedEmployee}
            onUpdated={handleUpdated}
          />
        </div>
      )}

      {isDialogOpen && (
        <CreateEmployeeDialog
          onClose={() => setIsDialogOpen(false)}
          onCreated={handleCreated}
        />
      )}

      {accountDialogEmployee && (
        <CreateUserAccountDialog
          employee={accountDialogEmployee}
          onClose={() => setAccountDialogEmployee(null)}
          onCreated={handleAccountCreated}
        />
      )}
    </div>
  );
}
