"use client";

import { useCallback, useMemo, useState, useSyncExternalStore } from "react";

import Alert from "@mui/material/Alert";
import Box from "@mui/material/Box";
import Stack from "@mui/material/Stack";
import { alpha, useTheme } from "@mui/material/styles";
import type { GridFilterModel, GridPaginationModel, GridSortModel } from "@mui/x-data-grid";

import { Heading } from "@/components/ui/heading";
import { AddStakeholderUserDialog } from "@/features/stakeholder/components/add-stakeholder-user-dialog";
import { DeleteStakeholderDialog } from "@/features/stakeholder/components/delete-stakeholder-dialog";
import { StakeholderFormDialog } from "@/features/stakeholder/components/stakeholder-form-dialog";
import {
  defaultStakeholderScreenFilters,
  StakeholderFilters,
  type StakeholderScreenFilters,
} from "@/features/stakeholder/components/stakeholder-filters";
import { StakeholderHeaderActions } from "@/features/stakeholder/components/stakeholder-header-actions";
import { StakeholderSummaryCards } from "@/features/stakeholder/components/stakeholder-summary-cards";
import { StakeholderTable } from "@/features/stakeholder/components/table/stakeholder-table";
import {
  STAKEHOLDER_PAGE_SIZE,
  type StakeholderViewMode,
} from "@/features/stakeholder/components/table/stakeholder-table-config";
import { ViewStakeholderDialog } from "@/features/stakeholder/components/view-stakeholder-dialog";
import { StakeholderViewToggle } from "@/features/stakeholder/components/stakeholder-view-toggle";
import { useStakeholders } from "@/features/stakeholder/hook/use-stakeholder";
import { buildStakeholderListQuery } from "@/features/stakeholder/stakeholder-list-query";
import type {
  Stakeholder,
  StakeholderFormPayload,
} from "@/features/stakeholder/stakeholder-data";

type FormMode = "create" | "edit";

const INITIAL_PAGINATION: GridPaginationModel = {
  page: 0,
  pageSize: STAKEHOLDER_PAGE_SIZE,
};

const INITIAL_FILTER: GridFilterModel = {
  items: [],
};

const STAKEHOLDER_VIEW_STORAGE_KEY = "stakeholder-view-mode";
const STAKEHOLDER_VIEW_CHANGE_EVENT = "stakeholder-view-mode-change";

function normalizeViewMode(value: string | null): StakeholderViewMode {
  return value === "grid" || value === "list" ? value : "list";
}

function getViewModeSnapshot(): StakeholderViewMode {
  if (typeof window === "undefined") {
    return "list";
  }

  return normalizeViewMode(
    window.localStorage.getItem(STAKEHOLDER_VIEW_STORAGE_KEY),
  );
}

function getServerViewModeSnapshot(): StakeholderViewMode {
  return "list";
}

function subscribeViewMode(callback: () => void) {
  if (typeof window === "undefined") {
    return () => {};
  }

  const handleStorage = (event: StorageEvent) => {
    if (event.key === STAKEHOLDER_VIEW_STORAGE_KEY) {
      callback();
    }
  };

  window.addEventListener(STAKEHOLDER_VIEW_CHANGE_EVENT, callback);
  window.addEventListener("storage", handleStorage);

  return () => {
    window.removeEventListener(STAKEHOLDER_VIEW_CHANGE_EVENT, callback);
    window.removeEventListener("storage", handleStorage);
  };
}

export function StakeholderScreen() {
  const theme = useTheme();
  const isDark = theme.palette.mode === "dark";

  const [formMode, setFormMode] = useState<FormMode | null>(null);
  const [selectedStakeholder, setSelectedStakeholder] =
      useState<Stakeholder | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<Stakeholder | null>(null);
  const [viewTarget, setViewTarget] = useState<Stakeholder | null>(null);
  const [addUserTarget, setAddUserTarget] = useState<Stakeholder | null>(null);
  const [searchTerm, setSearchTerm] = useState("");
  const [screenFilters, setScreenFilters] = useState<StakeholderScreenFilters>(
    defaultStakeholderScreenFilters,
  );
  const [paginationModel, setPaginationModel] =
      useState<GridPaginationModel>(INITIAL_PAGINATION);
  const [sortModel, setSortModel] = useState<GridSortModel>([]);
  const [filterModel, setFilterModel] = useState<GridFilterModel>(INITIAL_FILTER);

  const viewMode = useSyncExternalStore(
    subscribeViewMode,
    getViewModeSnapshot,
    getServerViewModeSnapshot,
  );

  const handleViewModeChange = useCallback((nextViewMode: StakeholderViewMode) => {
    window.localStorage.setItem(STAKEHOLDER_VIEW_STORAGE_KEY, nextViewMode);
    window.dispatchEvent(new Event(STAKEHOLDER_VIEW_CHANGE_EVENT));
  }, []);

  const listQuery = useMemo(
    () =>
      buildStakeholderListQuery({
        page: paginationModel.page + 1,
        limit: paginationModel.pageSize,
        search: searchTerm,
        sortModel,
        filterModel,
        screenFilters,
      }),
    [filterModel, paginationModel.page, paginationModel.pageSize, screenFilters, searchTerm, sortModel],
  );

  const {
    stakeholders,
    stakeholderOptions,
    listMeta,
    dashboardSummary,
    stakeholderTypes,
    stakeholderDetail,
    users,
    memberUserIds,

    isLoading,
    isLoadingStakeholders,
    isLoadingTypes,
    isLoadingDetail,
    isLoadingUsers,

    isSaving,
    isDeleting,
    isAssigningUser,

    error,
    successMessage,

    clearMessages,
    addStakeholder,
    editStakeholder,
    removeStakeholder,
    loadStakeholderDetail,
    clearStakeholderDetail,
    loadUsersForStakeholder,
    assignUserToStakeholder,
  } = useStakeholders(listQuery);

  const resetPaginationPage = useCallback(() => {
    setPaginationModel((current) =>
      current.page === 0 ? current : { ...current, page: 0 },
    );
  }, []);

  const handleSearchChange = useCallback(
    (value: string) => {
      setSearchTerm(value);
      resetPaginationPage();
    },
    [resetPaginationPage],
  );

  const handleScreenFiltersChange = useCallback(
    (filters: StakeholderScreenFilters) => {
      setScreenFilters(filters);
      resetPaginationPage();
    },
    [resetPaginationPage],
  );

  const handleSortModelChange = useCallback(
    (model: GridSortModel) => {
      setSortModel(model);
      resetPaginationPage();
    },
    [resetPaginationPage],
  );

  const handleFilterModelChange = useCallback(
    (model: GridFilterModel) => {
      setFilterModel(model);
      resetPaginationPage();
    },
    [resetPaginationPage],
  );

  const openCreateDialog = useCallback(() => {
    clearMessages();
    setSelectedStakeholder(null);
    setFormMode("create");
  }, [clearMessages]);

  const openEditDialog = useCallback(
      (stakeholder: Stakeholder) => {
        clearMessages();
        setSelectedStakeholder(stakeholder);
        setFormMode("edit");
      },
      [clearMessages],
  );

  const closeFormDialog = useCallback(() => {
    if (isSaving) {
      return;
    }

    setFormMode(null);
    setSelectedStakeholder(null);
  }, [isSaving]);

  const openViewDialog = useCallback(
      (stakeholder: Stakeholder) => {
        clearMessages();
        setViewTarget(stakeholder);
        void loadStakeholderDetail(stakeholder.id);
      },
      [clearMessages, loadStakeholderDetail],
  );

  const closeViewDialog = useCallback(() => {
    setViewTarget(null);
    clearStakeholderDetail();
  }, [clearStakeholderDetail]);

  const openAddUserDialog = useCallback(
      (stakeholder: Stakeholder) => {
        clearMessages();
        setAddUserTarget(stakeholder);
        void loadUsersForStakeholder(stakeholder.id);
      },
      [clearMessages, loadUsersForStakeholder],
  );

  const closeAddUserDialog = useCallback(() => {
    if (isAssigningUser) {
      return;
    }

    setAddUserTarget(null);
  }, [isAssigningUser]);

  const openDeleteDialog = useCallback(
      (stakeholder: Stakeholder) => {
        clearMessages();
        setDeleteTarget(stakeholder);
      },
      [clearMessages],
  );

  const closeDeleteDialog = useCallback(() => {
    if (isDeleting) {
      return;
    }

    setDeleteTarget(null);
  }, [isDeleting]);

  const handleSubmitStakeholder = useCallback(
      async (payload: StakeholderFormPayload) => {
        if (formMode === "create") {
          return addStakeholder(payload);
        }

        if (!selectedStakeholder) {
          return false;
        }

        return editStakeholder(selectedStakeholder.id, payload);
      },
      [addStakeholder, editStakeholder, formMode, selectedStakeholder],
  );

  const handleConfirmDelete = useCallback(async () => {
    if (!deleteTarget) {
      return;
    }

    const deleted = await removeStakeholder(deleteTarget.id);

    if (deleted) {
      setDeleteTarget(null);
    }
  }, [deleteTarget, removeStakeholder]);

  const handleAddUser = useCallback(
      async (stakeholderId: number, userId: number) => {
        return assignUserToStakeholder(stakeholderId, userId);
      },
      [assignUserToStakeholder],
  );

  return (
      <Box
          sx={{
            width: "100%",
            minHeight: "calc(100dvh - 64px)",
            display: "flex",
            flexDirection: "column",
            px: { xs: 2, sm: 3, lg: 2.5 },
            pt: { xs: 3, md: 3 },
            pb: { xs: 2, lg: 2 },
            color: theme.palette.text.primary,
          }}
      >
        <Box
          sx={{
            flex: 1,
            minHeight: 0,
            borderRadius: 3,
            display: "flex",
            flexDirection: "column",
          }}
        >
          <Heading
              title="Stakeholder"
              description="Manage stakeholders and their organizations"
              action={
                <StakeholderHeaderActions
                    searchTerm={searchTerm}
                    onSearchChange={handleSearchChange}
                    onAddStakeholder={openCreateDialog}
                />
              }
              titleSx={{
                fontWeight: 600,
                lineHeight: 1,
              }}
              descriptionSx={{
                mt: 1,
                fontSize: 12,
                color: isDark ? alpha("#ffffff", 0.72) : "#252b37",
              }}
          />

          <Stack spacing={1.5} sx={{ mb: error || successMessage ? 2 : 0 }}>
            {error ? (
                <Alert severity="error" onClose={clearMessages}>
                  {error}
                </Alert>
            ) : null}

            {successMessage ? (
                <Alert severity="success" onClose={clearMessages}>
                  {successMessage}
                </Alert>
            ) : null}
          </Stack>

          <Box
              sx={{
                mb: 2,
                display: "flex",
                alignItems: { xs: "stretch", md: "center" },
                justifyContent: "space-between",
                gap: { xs: 1.5, md: 2 },
                flexDirection: { xs: "column", md: "row" },
              }}
          >
            <StakeholderFilters
                filters={screenFilters}
                stakeholderTypes={stakeholderTypes}
                onChange={handleScreenFiltersChange}
            />

            <StakeholderViewToggle
                viewMode={viewMode}
                onViewModeChange={handleViewModeChange}
            />
          </Box>

          {viewMode === "list" ? (
            <Box sx={{ mb: 3 }}>
              <StakeholderSummaryCards summary={dashboardSummary} />
            </Box>
          ) : null}

          <Box
              sx={{
                flex: viewMode === "list" ? 1 : undefined,
                minHeight: 0,
                borderRadius: 2,
                bgcolor: isDark ? alpha("#ffffff", 0.04) : "transparent",
                display: "flex",
                flexDirection: "column",
              }}
          >
            <StakeholderTable
                stakeholders={stakeholders}
                rowCount={listMeta.total}
                paginationModel={paginationModel}
                onPaginationModelChange={setPaginationModel}
                sortModel={sortModel}
                onSortModelChange={handleSortModelChange}
                filterModel={filterModel}
                onFilterModelChange={handleFilterModelChange}
                viewMode={viewMode}
                isLoading={isLoading}
                error={stakeholders.length === 0 ? error : null}
                onView={openViewDialog}
                onAddUser={openAddUserDialog}
                onEdit={openEditDialog}
                onDelete={openDeleteDialog}
            />
          </Box>
        </Box>

        {formMode ? (
            <StakeholderFormDialog
                key={`${formMode}-${selectedStakeholder?.id ?? "new"}`}
                open
                mode={formMode}
                stakeholder={selectedStakeholder}
                stakeholderTypes={stakeholderTypes}
                stakeholders={stakeholderOptions}
                isLoadingTypes={isLoadingTypes}
                isLoadingStakeholders={isLoadingStakeholders}
                isSaving={isSaving}
                onClose={closeFormDialog}
                onSubmit={handleSubmitStakeholder}
            />
        ) : null}

        <DeleteStakeholderDialog
            stakeholder={deleteTarget}
            isDeleting={isDeleting}
            onClose={closeDeleteDialog}
            onConfirm={handleConfirmDelete}
        />

        {viewTarget ? (
            <ViewStakeholderDialog
                key={viewTarget.id}
                stakeholder={viewTarget}
                stakeholderDetail={stakeholderDetail}
                isLoading={isLoadingDetail}
                onClose={closeViewDialog}
            />
        ) : null}

        {addUserTarget ? (
            <AddStakeholderUserDialog
                key={addUserTarget.id}
                stakeholder={addUserTarget}
                users={users}
                memberUserIds={memberUserIds}
                isLoadingUsers={isLoadingUsers}
                isSaving={isAssigningUser}
                onClose={closeAddUserDialog}
                onSubmit={handleAddUser}
            />
        ) : null}
      </Box>
  );
}
