import React, { useEffect, useMemo, useState } from 'react';
import styled from 'styled-components';
import { isAxiosError } from 'axios';
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 { AppLayout } from '@/shared/components/layout/AppLayout';
import {
  AdminPanel,
  Button,
  Card,
  PanelLoadingState,
  PanelMessage} from '@/shared/components/ui';
import {
  getRole,
  listPermissions,
  listRoles,
  syncRolePermissions,
  type PermissionRecord,
  type RoleRecord} from '@/features/admin/services/roleAdminService';

const Workspace = styled.div`
  display: grid;
  grid-template-columns: minmax(220px, 280px) minmax(0, 1fr);
  gap: ${({ theme }) => theme.layout.cardGap};
  align-items: start;

  @media (max-width: 900px) {
    grid-template-columns: 1fr;
  }
`;

const RoleList = styled(Card)`
  padding: ${({ theme }) => theme.spacing[4]} !important;
`;

const RoleButton = styled.button<{ $active: boolean }>`
  display: block;
  width: 100%;
  text-align: start;
  padding: ${({ theme }) => `${theme.spacing[3]} ${theme.spacing[4]}`};
  border: 1px solid
    ${({ $active, theme }) => ($active ? theme.colors.primary : 'transparent')};
  border-radius: ${({ theme }) => theme.borderRadius.lg};
  background: ${({ $active, theme }) =>
    $active ? theme.colors.primaryLight : theme.colors.surfaceInset};
  color: ${({ theme }) => theme.colors.text.primary};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme, $active }) =>
    $active ? theme.typography.fontWeight.semibold : theme.typography.fontWeight.medium};
  cursor: pointer;
  margin-bottom: ${({ theme }) => theme.spacing[2]};
  transition:
    background-color ${({ theme }) => theme.transitions.fast},
    border-color ${({ theme }) => theme.transitions.fast};

  &:hover {
    background: ${({ theme }) => theme.colors.primaryLight};
    border-color: ${({ theme }) => theme.colors.borderSoft};
  }
`;

const PermissionPanel = styled(Card)`
  padding: ${({ theme }) => theme.layout.cardPaddingMd} !important;
`;

const ModuleBlock = styled.div`
  margin-bottom: ${({ theme }) => theme.spacing[6]};
  padding-bottom: ${({ theme }) => theme.spacing[5]};
  border-bottom: 1px solid ${({ theme }) => theme.colors.borderSoft};

  &:last-of-type {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
  }
`;

const ModuleTitle = styled.h3`
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};
  letter-spacing: ${({ theme }) => theme.typography.letterSpacing.wide};
  text-transform: uppercase;
  color: ${({ theme }) => theme.colors.text.tertiary};
  margin: 0 0 ${({ theme }) => theme.spacing[4]};
  text-align: start;
`;

const PermissionRow = styled.label`
  display: flex;
  align-items: flex-start;
  gap: ${({ theme }) => theme.spacing[3]};
  padding: ${({ theme }) => `${theme.spacing[2]} 0`};
  cursor: pointer;
  text-align: start;
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  color: ${({ theme }) => theme.colors.text.primary};
`;

const Warning = styled(PanelMessage).attrs({ $variant: 'warning' })`
  padding: ${({ theme }) => theme.spacing[4]};
  border-radius: ${({ theme }) => theme.borderRadius.lg};
  background: ${({ theme }) => theme.colors.warningLight};
  border: 1px solid ${({ theme }) => theme.colors.status.warning.border};
`;

const SaveRow = styled.div`
  display: flex;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[4]};
  flex-wrap: wrap;
  margin-top: ${({ theme }) => theme.spacing[6]};
  padding-top: ${({ theme }) => theme.spacing[6]};
  border-top: 1px solid ${({ theme }) => theme.colors.borderSoft};
`;

const SaveStatus = styled.p`
  margin: 0;
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  color: ${({ theme }) => theme.colors.text.secondary};
`;

function groupPermissions(permissions: PermissionRecord[]): Record<string, PermissionRecord[]> {
  return permissions.reduce<Record<string, PermissionRecord[]>>((groups, permission) => {
    const module = permission.name.split('.')[0] ?? 'other';
    if (!groups[module]) {
      groups[module] = [];
    }
    groups[module].push(permission);
    return groups;
  }, {});
}

function isDangerousPermission(name: string): boolean {
  const lower = name.toLowerCase();
  return lower.includes('delete') || lower.includes('manage') || lower.includes('super');
}

const AdminRolesPage: React.FC = () => {
  const { t } = useLocale();
  const user = useAuthStore((state) => state.user);
  const queryClient = useQueryClient();
  const [selectedRoleId, setSelectedRoleId] = useState<number | null>(null);
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([]);
  const [saveMessage, setSaveMessage] = useState<string | null>(null);

  const canManage = Boolean(user?.is_super_admin);

  const rolesQuery = useQuery({
    queryKey: ['admin', 'roles'],
    queryFn: listRoles,
    enabled: canManage});

  const permissionsQuery = useQuery({
    queryKey: ['admin', 'permissions'],
    queryFn: listPermissions,
    enabled: canManage});

  const globalRoles = useMemo(
    () => (rolesQuery.data ?? []).filter((role) => role.scope === 'global'),
    [rolesQuery.data],
  );

  const selectedRole = globalRoles.find((role) => role.id === selectedRoleId) ?? null;

  const roleDetailQuery = useQuery({
    queryKey: ['admin', 'roles', selectedRoleId],
    queryFn: () => getRole(selectedRoleId!),
    enabled: selectedRoleId != null && canManage});

  const grouped = useMemo(
    () => groupPermissions(permissionsQuery.data ?? []),
    [permissionsQuery.data],
  );

  useEffect(() => {
    if (globalRoles.length > 0 && selectedRoleId === null) {
      setSelectedRoleId(globalRoles[0].id);
    }
  }, [globalRoles, selectedRoleId]);

  useEffect(() => {
    if (roleDetailQuery.data?.permissions) {
      setSelectedPermissions(roleDetailQuery.data.permissions.map((p) => p.name));
    }
  }, [roleDetailQuery.data]);

  const saveMutation = useMutation({
    mutationFn: () => syncRolePermissions(selectedRoleId!, selectedPermissions),
    onSuccess: async () => {
      setSaveMessage(t('admin:roles.saveSuccess'));
      await queryClient.invalidateQueries({ queryKey: ['admin', 'roles'] });
    }});

  const togglePermission = (name: string) => {
    setSelectedPermissions((current) =>
      current.includes(name) ? current.filter((p) => p !== name) : [...current, name],
    );
  };

  const isForbidden =
    !canManage ||
    (rolesQuery.isError &&
      isAxiosError(rolesQuery.error) &&
      rolesQuery.error.response?.status === 403);

  return (
    <AppLayout>
      <AdminPageShell
        title={t('admin:roles.title')}
        subtitle={t('admin:roles.subtitle')}
        backLabel={t('settings:title')}
      >
      <AdminPanel>
        {isForbidden ? (
          <PanelMessage $variant="error">{t('admin:states.forbidden')}</PanelMessage>
        ) : rolesQuery.isLoading || permissionsQuery.isLoading ? (
          <PanelLoadingState label={t('common:status.loading')} />
        ) : (
          <Workspace>
            <RoleList variant="inset" padding="sm">
              {globalRoles.map((role: RoleRecord) => (
                <RoleButton
                  key={role.id}
                  type="button"
                  $active={role.id === selectedRoleId}
                  onClick={() => setSelectedRoleId(role.id)}
                >
                  {role.name}
                </RoleButton>
              ))}
            </RoleList>
            <PermissionPanel variant="elevated" padding="md">
              {selectedRole?.name === 'super_admin' && (
                <Warning>{t('admin:roles.superAdminWarning')}</Warning>
              )}
              {Object.entries(grouped).map(([module, permissions]) => (
                <ModuleBlock key={module}>
                  <ModuleTitle>{module}</ModuleTitle>
                  {permissions.map((permission) => (
                    <PermissionRow key={permission.id}>
                      <input
                        type="checkbox"
                        checked={selectedPermissions.includes(permission.name)}
                        onChange={() => togglePermission(permission.name)}
                      />
                      <span>
                        {permission.name}
                        {isDangerousPermission(permission.name) && (
                          <strong style={{ color: 'inherit', marginInlineStart: 8 }}>
                            ({t('admin:roles.dangerous')})
                          </strong>
                        )}
                      </span>
                    </PermissionRow>
                  ))}
                </ModuleBlock>
              ))}
              <SaveRow>
                <Button
                  variant="primary"
                  loading={saveMutation.isPending}
                  disabled={!selectedRoleId}
                  onClick={() => saveMutation.mutate()}
                >
                  {t('common:actions.save')}
                </Button>
                {saveMessage && <SaveStatus role="status">{saveMessage}</SaveStatus>}
              </SaveRow>
            </PermissionPanel>
          </Workspace>
        )}
      </AdminPanel>
      </AdminPageShell>
    </AppLayout>
  );
};

export default AdminRolesPage;
