import React, { useMemo, useState } from 'react';
import styled from 'styled-components';
import { isAxiosError } from 'axios';
import { Link } from 'react-router-dom';
import { AdminPageShell } from '@/features/admin/components/AdminPageShell';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useLocale } from '@/app/providers/LocaleProvider';
import { useAuthStore } from '@/features/auth/store/authStore';
import { usePermissions } from '@/features/auth/hooks/usePermissions';
import { PERMISSIONS } from '@/features/auth/constants/permissions';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import {Badge, Button, Input, Modal, Select, Table, Th, Td, Tr, AdminPanel, TableWrap, PanelLoadingState, PanelMessage} from '@/shared/components/ui';
import { ROUTES } from '@/shared/constants/routes';
import { listUsers, updateUser } from '@/features/admin/services/userAdminService';
import { listCompanies } from '@/features/admin/services/companyAdminService';
import { listDepartments } from '@/features/admin/services/departmentAdminService';
import {
  assignUserDepartment,
  listUserDepartments,
  removeUserDepartment,
  updateUserDepartment} from '@/features/admin/services/departmentMembershipService';
import type { UserRecord } from '@/features/admin/types/admin.types';
import type { Department } from '@/shared/types/api.types';
import { EmptyStateCard } from '@/features/onboarding/components/EmptyStateCard';

const DetailSection = styled.div`
  display: grid;
  gap: ${({ theme }) => theme.spacing[3]};
  margin-top: ${({ theme }) => theme.spacing[4]};
`;

const MembershipRow = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: ${({ theme }) => theme.spacing[2]};
  align-items: center;
  justify-content: space-between;
  padding: ${({ theme }) => theme.spacing[2]} 0;
  border-bottom: 1px solid ${({ theme }) => theme.colors.border};
`;

function isManagedDepartment(department: Department): boolean {
  const record = department as Department & {
    is_department_head?: boolean;
    is_manager?: boolean;
  };
  return Boolean(record.is_department_head || record.is_manager);
}

const AdminUsersPage: React.FC = () => {
  const { t } = useLocale();
  const user = useAuthStore((state) => state.user);
  const { isSuperAdmin, can } = usePermissions();
  const queryClient = useQueryClient();
  const [search, setSearch] = useState('');
  const [companyFilter, setCompanyFilter] = useState('');
  const [departmentFilter, setDepartmentFilter] = useState('');
  const [selectedUser, setSelectedUser] = useState<UserRecord | null>(null);
  const [addDepartmentId, setAddDepartmentId] = useState('');

  const managedDepartments = useMemo(
    () => (user?.departments ?? []).filter(isManagedDepartment),
    [user?.departments],
  );
  const isDepartmentHeadOnly =
    !isSuperAdmin &&
    !can(PERMISSIONS.COMPANY_USERS_MANAGE) &&
    can(PERMISSIONS.DEPARTMENT_USERS_MANAGE);
  const lockedDepartmentId = isDepartmentHeadOnly ? managedDepartments[0]?.id : undefined;

  const companiesQuery = useQuery({
    queryKey: ['admin', 'companies'],
    queryFn: () => listCompanies(),
    enabled: isSuperAdmin});

  const departmentsQuery = useQuery({
    queryKey: ['admin', 'departments', companyFilter || user?.company_id, isSuperAdmin],
    queryFn: () =>
      listDepartments(
        isSuperAdmin && companyFilter
          ? { company_id: companyFilter }
          : { company_id: user?.company_id },
      ),
    enabled: Boolean(user?.company_id) || Boolean(companyFilter)});

  const usersQuery = useQuery({
    queryKey: [
      'admin',
      'users',
      companyFilter,
      departmentFilter || lockedDepartmentId,
      search,
    ],
    queryFn: () =>
      listUsers({
        company_id: isSuperAdmin ? companyFilter || undefined : user?.company_id,
        department_id: departmentFilter || lockedDepartmentId || undefined,
        search: search || undefined}),
    enabled: Boolean(user?.company_id) || isSuperAdmin});

  const membershipsQuery = useQuery({
    queryKey: ['admin', 'users', selectedUser?.id, 'departments'],
    queryFn: () => listUserDepartments(selectedUser!.id),
    enabled: Boolean(selectedUser?.id)});

  const toggleMutation = useMutation({
    mutationFn: ({ id, is_active }: { id: string; is_active: boolean }) =>
      updateUser(id, { is_active }),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] });
    }});

  const assignMutation = useMutation({
    mutationFn: ({ userId, departmentId }: { userId: string; departmentId: string }) =>
      assignUserDepartment(userId, {
        department_id: departmentId,
        is_primary: (membershipsQuery.data?.length ?? 0) === 0}),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] });
      if (selectedUser) {
        await queryClient.invalidateQueries({
          queryKey: ['admin', 'users', selectedUser.id, 'departments']});
      }
      setAddDepartmentId('');
    }});

  const membershipMutation = useMutation({
    mutationFn: ({
      userId,
      departmentId,
      payload}: {
      userId: string;
      departmentId: string;
      payload: { is_primary?: boolean; is_department_head?: boolean };
    }) => updateUserDepartment(userId, departmentId, payload),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] });
      if (selectedUser) {
        await queryClient.invalidateQueries({
          queryKey: ['admin', 'users', selectedUser.id, 'departments']});
      }
    }});

  const removeMutation = useMutation({
    mutationFn: ({ userId, departmentId }: { userId: string; departmentId: string }) =>
      removeUserDepartment(userId, departmentId),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'users'] });
      if (selectedUser) {
        await queryClient.invalidateQueries({
          queryKey: ['admin', 'users', selectedUser.id, 'departments']});
      }
    }});

  const isForbidden =
    usersQuery.isError &&
    isAxiosError(usersQuery.error) &&
    usersQuery.error.response?.status === 403;

  const canManageHeads = isSuperAdmin || can(PERMISSIONS.DEPARTMENT_HEADS_MANAGE);
  const departmentOptions = (departmentsQuery.data ?? []).map((department) => ({
    value: department.id,
    label: department.name}));

  return (
    <AppLayout>
      <AdminPageShell
        title={t('admin:users.title')}
        subtitle={t('admin:users.subtitle')}
        backLabel={t('settings:title')}
        toolbar={
          <>
        <Input
          label={t('common:actions.search')}
          value={search}
          onChange={(event) => setSearch(event.target.value)}
          style={{ minWidth: 220 }}
        />
        {isSuperAdmin && (
          <Select
            label={t('admin:users.filters.company')}
            value={companyFilter}
            onChange={(event) => {
              setCompanyFilter(event.target.value);
              setDepartmentFilter('');
            }}
            options={[
              { value: '', label: t('admin:users.filters.allCompanies') },
              ...(companiesQuery.data ?? []).map((company) => ({
                value: company.id,
                label: company.name})),
            ]}
            style={{ minWidth: 200 }}
          />
        )}
        {!isDepartmentHeadOnly && (
          <Select
            label={t('admin:users.filters.department')}
            value={departmentFilter}
            onChange={(event) => setDepartmentFilter(event.target.value)}
            options={[
              { value: '', label: t('admin:users.filters.allDepartments') },
              ...departmentOptions,
            ]}
            style={{ minWidth: 200 }}
          />
        )}
        {isDepartmentHeadOnly && lockedDepartmentId && (
          <Input
            label={t('admin:users.filters.department')}
            value={managedDepartments[0]?.name ?? ''}
            readOnly
            style={{ minWidth: 200 }}
          />
        )}
        <Link to={ROUTES.ADMIN_INVITES}>
          <Button variant="secondary">{t('admin:users.manageInvites')}</Button>
        </Link>
          </>
        }
      >
      <AdminPanel>
        {isForbidden ? (
          <PanelMessage $variant="error">{t('admin:states.forbidden')}</PanelMessage>
        ) : usersQuery.isLoading ? (
          <PanelLoadingState />
        ) : usersQuery.isError ? (
          <PanelMessage $variant="error">{t('admin:states.error')}</PanelMessage>
        ) : (usersQuery.data?.length ?? 0) === 0 ? (
          <EmptyStateCard
            icon="👥"
            title={t('onboarding:emptyStates.users.title')}
            description={t('onboarding:emptyStates.users.description')}
            actionLabel={t('onboarding:emptyStates.users.action')}
            onAction={() => window.location.assign(ROUTES.ADMIN_INVITES)}
          />
        ) : (
          <TableWrap>
            <Table>
              <thead>
                <tr>
                  <Th>{t('admin:users.columns.name')}</Th>
                  <Th>{t('admin:users.columns.email')}</Th>
                  <Th>{t('admin:users.columns.departments')}</Th>
                  <Th>{t('admin:users.columns.status')}</Th>
                  <Th>{t('admin:users.columns.actions')}</Th>
                </tr>
              </thead>
              <tbody>
                {usersQuery.data?.map((row) => (
                  <Tr key={row.id}>
                    <Td>{row.name}</Td>
                    <Td>{row.email}</Td>
                    <Td>
                      {(row.departments ?? [])
                        .map((department) => department.name)
                        .join(', ') || '—'}
                    </Td>
                    <Td>
                      <Badge variant={row.is_active ? 'success' : 'gray'}>
                        {row.is_active ? t('admin:users.active') : t('admin:users.inactive')}
                      </Badge>
                    </Td>
                    <Td>
                      <Button size="sm" variant="ghost" onClick={() => setSelectedUser(row)}>
                        {t('admin:users.manage')}
                      </Button>
                      {row.id !== user?.id && !row.is_super_admin && (
                        <Button
                          size="sm"
                          variant="secondary"
                          onClick={() =>
                            toggleMutation.mutate({
                              id: row.id,
                              is_active: !row.is_active})
                          }
                        >
                          {row.is_active
                            ? t('admin:users.deactivate')
                            : t('admin:users.activate')}
                        </Button>
                      )}
                    </Td>
                  </Tr>))}
              </tbody>
            </Table>
          </TableWrap>
        )}
      </AdminPanel>
      </AdminPageShell>

      <Modal
        isOpen={Boolean(selectedUser)}
        onClose={() => setSelectedUser(null)}
        title={selectedUser?.name ?? t('admin:users.title')}
      >
        {selectedUser && (
          <DetailSection>
            <p style={{ margin: 0 }}>{selectedUser.email}</p>
            <h3 style={{ margin: 0 }}>{t('admin:users.departmentMemberships')}</h3>

            {membershipsQuery.isLoading ? (
              <PanelLoadingState />
            ) : (
              (membershipsQuery.data ?? []).map((membership) => (
                <MembershipRow key={membership.id}>
                  <div>
                    <strong>{membership.department?.name ?? membership.department_id}</strong>
                    <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginTop: 4 }}>
                      {membership.is_primary && (
                        <Badge variant="info">{t('admin:users.primaryDepartment')}</Badge>
                      )}
                      {membership.is_department_head && (
                        <Badge variant="warning">{t('admin:users.departmentHead')}</Badge>
                      )}
                    </div>
                  </div>
                  <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                    {!membership.is_primary && (
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() =>
                          membershipMutation.mutate({
                            userId: selectedUser.id,
                            departmentId: membership.department_id,
                            payload: { is_primary: true }})
                        }
                      >
                        {t('admin:users.setPrimary')}
                      </Button>
                    )}
                    {canManageHeads && !membership.is_department_head && (
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() =>
                          membershipMutation.mutate({
                            userId: selectedUser.id,
                            departmentId: membership.department_id,
                            payload: { is_department_head: true }})
                        }
                      >
                        {t('admin:users.setDepartmentHead')}
                      </Button>
                    )}
                    {canManageHeads && membership.is_department_head && (
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() =>
                          membershipMutation.mutate({
                            userId: selectedUser.id,
                            departmentId: membership.department_id,
                            payload: { is_department_head: false }})
                        }
                      >
                        {t('admin:users.unsetDepartmentHead')}
                      </Button>
                    )}
                    <Button
                      size="sm"
                      variant="secondary"
                      onClick={() =>
                        removeMutation.mutate({
                          userId: selectedUser.id,
                          departmentId: membership.department_id})
                      }
                    >
                      {t('admin:users.removeDepartment')}
                    </Button>
                  </div>
                </MembershipRow>
              ))
            )}

            {(isSuperAdmin || can(PERMISSIONS.DEPARTMENT_USERS_MANAGE)) && (
              <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'flex-end' }}>
                {isDepartmentHeadOnly ? (
                  <Input
                    label={t('admin:users.addDepartment')}
                    value={managedDepartments[0]?.name ?? ''}
                    readOnly
                  />
                ) : (
                  <Select
                    label={t('admin:users.addDepartment')}
                    value={addDepartmentId}
                    onChange={(event) => setAddDepartmentId(event.target.value)}
                    options={[
                      { value: '', label: t('admin:users.selectDepartment') },
                      ...departmentOptions.filter(
                        (option) =>
                          !(membershipsQuery.data ?? []).some(
                            (membership) => membership.department_id === option.value,
                          ),
                      ),
                    ]}
                    style={{ minWidth: 220 }}
                  />
                )}
                <Button
                  variant="primary"
                  disabled={!(addDepartmentId || lockedDepartmentId)}
                  loading={assignMutation.isPending}
                  onClick={() =>
                    assignMutation.mutate({
                      userId: selectedUser.id,
                      departmentId: addDepartmentId || lockedDepartmentId!})
                  }
                >
                  {t('admin:users.addToDepartment')}
                </Button>
              </div>
            )}
          </DetailSection>
        )}
      </Modal>
    </AppLayout>
  );
};

export default AdminUsersPage;
