import React, { useMemo, useState } from 'react';
import styled from 'styled-components';
import { isAxiosError } from 'axios';
import { Link } from 'react-router-dom';
import { useLocale } from '@/app/providers/LocaleProvider';
import { useAuthStore } from '@/features/auth/store/authStore';
import type { SettingsRequestContext } from '@/features/settings/services/settingsService';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import { Button, Card, Select, Spinner } from '@/shared/components/ui';
import { ROUTES } from '@/shared/constants/routes';
import { SettingFieldRow } from '@/features/settings/components/SettingFieldRow';
import { SettingsForbidden } from '@/features/settings/components/SettingsForbidden';
import { useSettingGroups } from '@/features/settings/hooks/useSettingGroups';
import { useSettingsDepartmentScope } from '@/features/settings/hooks/useSettingsDepartmentScope';
import { useSettings } from '@/features/settings/hooks/useSettings';
import { useSettingMutations } from '@/features/settings/hooks/useSettingMutations';
import type { SettingItem, SettingScope } from '@/features/settings/types/settings.types';

const Title = styled.h1`
  font-size: ${({ theme }) => theme.typography.fontSize['3xl']};
  margin-bottom: ${({ theme }) => theme.spacing[2]};
  text-align: start;
`;

const SubNav = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: ${({ theme }) => theme.spacing[3]};
  margin-bottom: ${({ theme }) => theme.spacing[6]};
`;

const TabContainer = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: ${({ theme }) => theme.spacing[2]};
  margin-bottom: ${({ theme }) => theme.spacing[4]};
  border-bottom: 1px solid ${({ theme }) => theme.colors.border};
`;

const Tab = styled.button<{ $active: boolean }>`
  padding: ${({ theme }) => `${theme.spacing[3]} ${theme.spacing[4]}`};
  background: none;
  border: none;
  border-bottom: 2px solid
    ${({ $active, theme }) => ($active ? theme.colors.primary : 'transparent')};
  color: ${({ $active, theme }) =>
    $active ? theme.colors.primary : theme.colors.text.secondary};
  font-weight: ${({ theme }) => theme.typography.fontWeight.medium};
  cursor: pointer;
`;

const Toolbar = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: ${({ theme }) => theme.spacing[4]};
  align-items: flex-end;
  margin-bottom: ${({ theme }) => theme.spacing[4]};
`;

const Centered = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[3]};
  padding: ${({ theme }) => theme.spacing[12]} ${({ theme }) => theme.spacing[4]};
  color: ${({ theme }) => theme.colors.text.secondary};
  text-align: center;
`;

const SettingsPage: React.FC = () => {
  const { t } = useLocale();
  const user = useAuthStore((state) => state.user);
  const {
    departments,
    departmentId,
    setDepartmentId,
    needsDepartmentSelection,
    isDepartmentContextReady,
    isLoadingDepartments,
  } = useSettingsDepartmentScope();
  const groupsQuery = useSettingGroups();
  const [activeGroup, setActiveGroup] = useState<string>('');
  const [scope, setScope] = useState<SettingScope>('department');
  const [fieldErrors, setFieldErrors] = useState<Record<string, string>>({});
  const [saveKey, setSaveKey] = useState<string | null>(null);

  const settingsContext = useMemo<SettingsRequestContext | undefined>(() => {
    if (scope === 'department') {
      if (!departmentId) {
        return undefined;
      }
      return { scope: 'department', departmentId };
    }
    if (scope === 'company') {
      if (!user?.company_id) {
        return undefined;
      }
      return { scope: 'company', companyId: user.company_id };
    }
    if (scope === 'global') {
      return { scope: 'global' };
    }
    return undefined;
  }, [scope, departmentId, user?.company_id]);

  const isSettingsContextReady =
    scope === 'department'
      ? isDepartmentContextReady
      : scope === 'company'
        ? Boolean(user?.company_id)
        : true;

  const selectedGroup = activeGroup || groupsQuery.data?.[0] || 'general';
  const settingsQuery = useSettings(selectedGroup, settingsContext, isSettingsContextReady);
  const mutations = useSettingMutations(selectedGroup, settingsContext);

  const settingsList = useMemo(() => {
    const map = settingsQuery.data ?? {};
    return Object.values(map).sort((a, b) => a.key.localeCompare(b.key));
  }, [settingsQuery.data]);

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

  const needsDepartmentScope =
    scope === 'department' && (isLoadingDepartments || !isDepartmentContextReady);

  const contextErrorMessage =
    settingsQuery.isError &&
    isAxiosError(settingsQuery.error) &&
    settingsQuery.error.response?.status === 422
      ? typeof settingsQuery.error.response.data === 'object' &&
        settingsQuery.error.response.data !== null &&
        'message' in settingsQuery.error.response.data &&
        typeof (settingsQuery.error.response.data as { message: unknown }).message === 'string'
        ? (settingsQuery.error.response.data as { message: string }).message
        : t('settings:states.departmentRequired')
      : null;

  const canEdit = Boolean(user);
  const isSuperAdmin = user?.roles?.some((role) =>
    role.name.toLowerCase().includes('super') || role.name.toLowerCase().includes('admin'),
  );
  const canEditCompany = Boolean(isSuperAdmin);
  const canEditGlobal = Boolean(isSuperAdmin);

  const scopeOptions = [
    { value: 'department', label: t('settings:scope.department'), disabled: false },
    {
      value: 'company',
      label: t('settings:scope.company'),
      disabled: !canEditCompany,
    },
    { value: 'global', label: t('settings:scope.global'), disabled: !canEditGlobal },
  ];

  const handleSave = async (key: string, value: unknown) => {
    setSaveKey(key);
    setFieldErrors((current) => ({ ...current, [key]: '' }));
    try {
      await mutations.updateMutation.mutateAsync({ key, value, scope });
    } catch (error) {
      if (isAxiosError(error) && error.response?.status === 422) {
        const raw = error.response.data;
        const message =
          typeof raw === 'object' &&
          raw !== null &&
          'message' in raw &&
          typeof (raw as { message: unknown }).message === 'string'
            ? (raw as { message: string }).message
            : t('settings:states.validationError');
        setFieldErrors((current) => ({ ...current, [key]: message }));
      }
    } finally {
      setSaveKey(null);
    }
  };

  const handleReset = async (key: string) => {
    setSaveKey(key);
    try {
      await mutations.resetMutation.mutateAsync({ key, scope });
    } finally {
      setSaveKey(null);
    }
  };

  return (
    <AppLayout>
      <Title>{t('settings:title')}</Title>
      <p style={{ color: 'var(--text-secondary)', margin: '0 0 24px', textAlign: 'start' }}>
        {t('settings:subtitle')}
      </p>

      <SubNav>
        <Link to={ROUTES.ADMIN_USERS}>
          <Button variant="outline">{t('admin:nav.users')}</Button>
        </Link>
        <Link to={ROUTES.ADMIN_INVITES}>
          <Button variant="outline">{t('admin:nav.invites')}</Button>
        </Link>
        <Link to={ROUTES.ADMIN_DEPARTMENTS}>
          <Button variant="outline">{t('admin:nav.departments')}</Button>
        </Link>
        <Link to={ROUTES.ADMIN_CATEGORIES}>
          <Button variant="outline">{t('admin:nav.categories')}</Button>
        </Link>
        <Link to={ROUTES.SETTINGS_SLA}>
          <Button variant="outline">{t('admin:nav.sla')}</Button>
        </Link>
        <Link to={ROUTES.ADMIN_AUDIT_LOGS}>
          <Button variant="outline">{t('admin:nav.audit')}</Button>
        </Link>
      </SubNav>

      {groupsQuery.isLoading ? (
        <Centered role="status">
          <Spinner />
        </Centered>
      ) : (
        <>
          <TabContainer>
            {(groupsQuery.data ?? ['general']).map((group) => (
              <Tab
                key={group}
                type="button"
                $active={selectedGroup === group}
                onClick={() => setActiveGroup(group)}
              >
                {t(`settings:groups.${group}`, { defaultValue: group })}
              </Tab>
            ))}
          </TabContainer>

          <Toolbar>
            <Select
              label={t('settings:scope.label')}
              value={scope}
              onChange={(event) => setScope(event.target.value as SettingScope)}
              options={scopeOptions}
              style={{ minWidth: 200 }}
            />
            {scope === 'department' && needsDepartmentSelection && (
              <Select
                label={t('settings:scope.departmentSelect')}
                value={departmentId}
                onChange={(event) => setDepartmentId(event.target.value)}
                options={[
                  { value: '', label: t('settings:states.departmentRequired') },
                  ...departments.map((d) => ({ value: d.id, label: d.name })),
                ]}
                style={{ minWidth: 240 }}
              />
            )}
          </Toolbar>

          {needsDepartmentScope ? (
            <Card variant="outlined" padding="lg">
              <p role="status" style={{ margin: 0, color: 'var(--text-secondary)' }}>
                {isLoadingDepartments
                  ? t('settings:states.loadingDepartments')
                  : t('settings:states.departmentRequired')}
              </p>
            </Card>
          ) : contextErrorMessage ? (
            <Card variant="outlined" padding="lg">
              <p role="alert" style={{ margin: 0, color: '#DC2626' }}>
                {contextErrorMessage}
              </p>
            </Card>
          ) : isForbidden ? (
            <SettingsForbidden onRetry={() => settingsQuery.refetch()} />
          ) : settingsQuery.isLoading ? (
            <Centered role="status">
              <Spinner size="lg" />
              <p>{t('settings:states.loading')}</p>
            </Centered>
          ) : settingsQuery.isError ? (
            <Centered role="alert">
              <p>{t('settings:states.error')}</p>
              <Button variant="primary" onClick={() => settingsQuery.refetch()}>
                {t('settings:states.retry')}
              </Button>
            </Centered>
          ) : settingsList.length === 0 ? (
            <Card variant="outlined" padding="lg">
              <p style={{ margin: 0, color: 'var(--text-secondary)' }}>
                {t('settings:states.empty')}
              </p>
            </Card>
          ) : (
            <Card variant="outlined" padding="lg" data-tour="settings-panel">
              {settingsList.map((setting: SettingItem) => (
                <SettingFieldRow
                  key={setting.key}
                  setting={setting}
                  scope={scope}
                  canEdit={canEdit && (scope !== 'global' || canEditGlobal)}
                  isSaving={saveKey === setting.key && mutations.updateMutation.isPending}
                  fieldError={fieldErrors[setting.key]}
                  onSave={handleSave}
                  onReset={handleReset}
                />
              ))}
            </Card>
          )}
        </>
      )}
    </AppLayout>
  );
};

export default SettingsPage;
