import React, { 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 { useTicketDepartments } from '@/features/tickets/hooks/useTicketDepartments';
import { AppLayout } from '@/shared/components/layout/AppLayout';
import {Button, Input, Modal, Select, Table, Th, Td, Tr, AdminPanel, TableWrap, PanelLoadingState, PanelMessage} from '@/shared/components/ui';
import { fetchSlaPolicies } from '@/features/admin/services/adminService';
import {
  createCategory,
  createSubcategory,
  deleteCategory,
  deleteSubcategory,
  listCategories,
  updateCategory,
  updateSubcategory} from '@/features/admin/services/categoryAdminService';
import type { CategoryRecord, SubcategoryRecord } from '@/features/admin/types/admin.types';
import { localizedName } from '@/features/tickets/utils/ticketDisplay';
import { invalidateTicketFormOptions } from '@/features/tickets/utils/invalidateTicketFormOptions';
import { EmptyStateCard } from '@/features/onboarding/components/EmptyStateCard';
import { AdminActionsHeader, AdminRowActions } from '@/features/admin/components/AdminRowActions';

const Actions = styled.div`
  display: flex;
  gap: ${({ theme }) => theme.spacing[2]};
  flex-wrap: wrap;
`;

const FormGrid = styled.div`
  display: grid;
  gap: ${({ theme }) => theme.spacing[3]};
`;

const emptyCategoryForm = { name_en: '', name_ar: '', sla_policy_id: '', sort_order: 0 };
const emptySubForm = { name_en: '', name_ar: '', sla_policy_id: '', sort_order: 0 };

const AdminCategoriesPage: React.FC = () => {
  const { t, locale } = useLocale();
  const user = useAuthStore((state) => state.user);
  const {
    departments,
    departmentId,
    setDepartmentId,
    companyId,
    setCompanyId,
    companies,
    isSuperAdmin,
    isLoadingCompanies,
    isLoadingDepartments,
    hasCompany,
    hasDepartments,
  } = useTicketDepartments();
  const queryClient = useQueryClient();
  const [categoryModalOpen, setCategoryModalOpen] = useState(false);
  const [subModalOpen, setSubModalOpen] = useState(false);
  const [categoryForm, setCategoryForm] = useState(emptyCategoryForm);
  const [subForm, setSubForm] = useState(emptySubForm);
  const [parentCategory, setParentCategory] = useState<CategoryRecord | null>(null);
  const [editingCategory, setEditingCategory] = useState<CategoryRecord | null>(null);
  const [editingSub, setEditingSub] = useState<SubcategoryRecord | null>(null);

  const companyOptions = useMemo(
    () => [
      { value: '', label: t('admin:users.selectCompany') },
      ...companies.map((company) => ({ value: company.id, label: company.name })),
    ],
    [companies, t],
  );

  const departmentOptions = useMemo(
    () => [
      { value: '', label: t('admin:users.selectDepartment') },
      ...departments.map((department) => ({ value: department.id, label: department.name })),
    ],
    [departments, t],
  );

  const lockedCompanyLabel = user?.company?.name ?? '';

  const categoriesQuery = useQuery({
    queryKey: ['admin', 'categories', departmentId],
    queryFn: () => listCategories(departmentId),
    enabled: Boolean(departmentId)});

  const slaQuery = useQuery({
    queryKey: ['admin', 'sla-picker', departmentId],
    queryFn: () => fetchSlaPolicies(departmentId),
    enabled: Boolean(departmentId)});

  const saveCategoryMutation = useMutation({
    mutationFn: async () => {
      const payload = {
        name_en: categoryForm.name_en,
        name_ar: categoryForm.name_ar,
        sla_policy_id: categoryForm.sla_policy_id || null,
        sort_order: categoryForm.sort_order,
      };
      if (editingCategory) {
        return updateCategory(editingCategory.id, payload);
      }
      return createCategory({
        department_id: departmentId,
        ...payload,
        is_active: true,
      });
    },
    onSuccess: async () => {
      setCategoryModalOpen(false);
      setEditingCategory(null);
      setCategoryForm(emptyCategoryForm);
      await queryClient.invalidateQueries({ queryKey: ['admin', 'categories', departmentId] });
      await invalidateTicketFormOptions(queryClient, departmentId);
    }});

  const saveSubMutation = useMutation({
    mutationFn: async () => {
      if (!parentCategory) {
        return;
      }
      if (editingSub) {
        return updateSubcategory(editingSub.id, {
          name_en: subForm.name_en,
          name_ar: subForm.name_ar,
          sla_policy_id: subForm.sla_policy_id || null,
          sort_order: subForm.sort_order});
      }
      return createSubcategory(parentCategory.id, {
        name_en: subForm.name_en,
        name_ar: subForm.name_ar,
        sla_policy_id: subForm.sla_policy_id || null,
        sort_order: subForm.sort_order,
      });
    },
    onSuccess: async () => {
      setSubModalOpen(false);
      setEditingSub(null);
      setParentCategory(null);
      setSubForm(emptySubForm);
      await queryClient.invalidateQueries({ queryKey: ['admin', 'categories', departmentId] });
      await invalidateTicketFormOptions(queryClient, departmentId);
    }});

  const deleteCategoryMutation = useMutation({
    mutationFn: (id: string) => deleteCategory(id),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'categories', departmentId] });
      await invalidateTicketFormOptions(queryClient, departmentId);
    }});

  const deleteSubMutation = useMutation({
    mutationFn: (id: string) => deleteSubcategory(id),
    onSuccess: async () => {
      await queryClient.invalidateQueries({ queryKey: ['admin', 'categories', departmentId] });
      await invalidateTicketFormOptions(queryClient, departmentId);
    }});

  const openCreateCategory = () => {
    setEditingCategory(null);
    setCategoryForm(emptyCategoryForm);
    setCategoryModalOpen(true);
  };

  const openEditCategory = (category: CategoryRecord) => {
    setEditingCategory(category);
    setCategoryForm({
      name_en: category.name_en,
      name_ar: category.name_ar,
      sla_policy_id: category.sla_policy_id ?? '',
      sort_order: category.sort_order,
    });
    setCategoryModalOpen(true);
  };

  const openCreateSub = (category: CategoryRecord) => {
    setParentCategory(category);
    setEditingSub(null);
    setSubForm({
      ...emptySubForm,
      sla_policy_id: category.sla_policy_id ?? '',
    });
    setSubModalOpen(true);
  };

  const openEditSub = (category: CategoryRecord, sub: SubcategoryRecord) => {
    setParentCategory(category);
    setEditingSub(sub);
    setSubForm({
      name_en: sub.name_en,
      name_ar: sub.name_ar,
      sla_policy_id: sub.sla_policy_id ?? '',
      sort_order: sub.sort_order});
    setSubModalOpen(true);
  };

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

  const slaOptions = [
    { value: '', label: t('admin:categories.noSla') },
    ...(slaQuery.data ?? []).map((policy) => ({
      value: policy.id,
      label: localizedName(policy, locale)})),
  ];

  return (
    <AppLayout>
      <AdminPageShell
        title={t('admin:categories.title')}
        subtitle={t('admin:categories.subtitle')}
        backLabel={t('settings:title')}
        toolbar={
          <>
        {isSuperAdmin ? (
          <Select
            label={t('admin:users.filters.company')}
            value={companyId}
            onChange={(event) => setCompanyId(event.target.value)}
            options={companyOptions}
            disabled={isLoadingCompanies}
            style={{ minWidth: 220 }}
          />
        ) : (
          <Input
            label={t('admin:users.filters.company')}
            value={lockedCompanyLabel}
            readOnly
            style={{ minWidth: 220 }}
          />
        )}
        <Select
          label={t('admin:categories.department')}
          value={departmentId}
          onChange={(event) => setDepartmentId(event.target.value)}
          options={departmentOptions}
          disabled={isLoadingDepartments || !hasCompany || !hasDepartments}
          style={{ minWidth: 240 }}
        />
        <Button variant="primary" onClick={openCreateCategory} disabled={!departmentId}>
          {t('admin:categories.create')}
        </Button>
          </>
        }
      >
      <AdminPanel>
        {isSuperAdmin && !hasCompany ? (
          <p style={{ margin: 0 }}>{t('admin:departments.companyRequired')}</p>
        ) : isForbidden ? (
          <PanelMessage $variant="error">{t('admin:states.forbidden')}</PanelMessage>
        ) : categoriesQuery.isLoading ? (
          <PanelLoadingState />
        ) : categoriesQuery.isError ? (
          <PanelMessage $variant="error">{t('admin:states.error')}</PanelMessage>
        ) : (categoriesQuery.data?.length ?? 0) === 0 ? (
          <EmptyStateCard
            icon="📁"
            title={t('onboarding:emptyStates.categories.title')}
            description={t('onboarding:emptyStates.categories.description')}
            actionLabel={t('onboarding:emptyStates.categories.action')}
            onAction={openCreateCategory}
            actionDisabled={!departmentId}
          />
        ) : (
          <TableWrap>
            <Table>
              <thead>
                <tr>
                  <Th>{t('admin:categories.category')}</Th>
                  <Th>{t('admin:categories.subcategory')}</Th>
                  <Th>{t('admin:categories.actions')}</Th>
                  <AdminActionsHeader />
                </tr>
              </thead>
              <tbody>
                {categoriesQuery.data?.flatMap((category) => {
                  const subs = category.subcategories ?? [];
                  if (subs.length === 0) {
                    return (
                      <Tr key={category.id}>
                        <Td>{localizedName(category, locale)}</Td>
                        <Td>—</Td>
                        <Td>
                          <Actions>
                            <Button size="sm" variant="secondary" onClick={() => openCreateSub(category)}>
                              {t('admin:categories.addSubcategory')}
                            </Button>
                          </Actions>
                        </Td>
                        <AdminRowActions
                          editLabel={t('common:actions.edit')}
                          deleteLabel={t('common:actions.delete')}
                          confirmDelete={t('admin:categories.confirmDelete')}
                          onEdit={() => openEditCategory(category)}
                          onDelete={() => deleteCategoryMutation.mutate(category.id)}
                        />
                      </Tr>
                    );
                  }
                  return subs.map((sub, index) => (
                    <Tr key={`${category.id}-${sub.id}`}>
                      <Td>{index === 0 ? localizedName(category, locale) : ''}</Td>
                      <Td>{localizedName(sub, locale)}</Td>
                      <Td>
                        {index === 0 ? (
                          <Actions>
                            <Button size="sm" variant="secondary" onClick={() => openCreateSub(category)}>
                              {t('admin:categories.addSubcategory')}
                            </Button>
                            <Button size="sm" variant="secondary" onClick={() => openEditCategory(category)}>
                              {t('admin:categories.editCategory')}
                            </Button>
                          </Actions>
                        ) : null}
                      </Td>
                      <AdminRowActions
                        editLabel={t('common:actions.edit')}
                        deleteLabel={t('common:actions.delete')}
                        confirmDelete={t('admin:categories.confirmDeleteSub')}
                        onEdit={() => openEditSub(category, sub)}
                        onDelete={() => deleteSubMutation.mutate(sub.id)}
                      />
                    </Tr>
                  ));
                })}
              </tbody>
            </Table>
          </TableWrap>
        )}
      </AdminPanel>
      </AdminPageShell>

      <Modal
        isOpen={categoryModalOpen}
        onClose={() => {
          setCategoryModalOpen(false);
          setEditingCategory(null);
        }}
        title={
          editingCategory ? t('admin:categories.editTitle') : t('admin:categories.createTitle')
        }
        footer={
          <>
            <Button
              variant="secondary"
              onClick={() => {
                setCategoryModalOpen(false);
                setEditingCategory(null);
              }}
            >
              {t('common:actions.cancel')}
            </Button>
            <Button
              variant="primary"
              loading={saveCategoryMutation.isPending}
              disabled={
                (!editingCategory && !departmentId) ||
                !categoryForm.name_en.trim() ||
                !categoryForm.name_ar.trim()
              }
              onClick={() => saveCategoryMutation.mutate()}
            >
              {t('common:actions.save')}
            </Button>
          </>
        }
      >
        <FormGrid>
          {!editingCategory && isSuperAdmin ? (
            <Select
              label={t('admin:users.filters.company')}
              value={companyId}
              onChange={(event) => setCompanyId(event.target.value)}
              options={companyOptions}
              disabled={isLoadingCompanies}
              fullWidth
              required
            />
          ) : !editingCategory ? (
            <Input
              label={t('admin:users.filters.company')}
              value={lockedCompanyLabel}
              readOnly
              fullWidth
            />
          ) : null}
          {!editingCategory ? (
            <Select
              label={t('admin:categories.department')}
              value={departmentId}
              onChange={(event) => setDepartmentId(event.target.value)}
              options={departmentOptions}
              disabled={isLoadingDepartments || !hasCompany || !hasDepartments}
              fullWidth
              required
            />
          ) : null}
          <Input
            label={t('admin:categories.nameEn')}
            value={categoryForm.name_en}
            onChange={(event) =>
              setCategoryForm((prev) => ({ ...prev, name_en: event.target.value }))
            }
            fullWidth
            required
          />
          <Input
            label={t('admin:categories.nameAr')}
            value={categoryForm.name_ar}
            onChange={(event) =>
              setCategoryForm((prev) => ({ ...prev, name_ar: event.target.value }))
            }
            fullWidth
            required
          />
          <Select
            label={t('admin:categories.slaPolicy')}
            value={categoryForm.sla_policy_id}
            onChange={(event) =>
              setCategoryForm((prev) => ({ ...prev, sla_policy_id: event.target.value }))
            }
            options={slaOptions}
            fullWidth
          />
          <Input
            label={t('admin:categories.sortOrder')}
            type="number"
            value={String(categoryForm.sort_order)}
            onChange={(event) =>
              setCategoryForm((prev) => ({
                ...prev,
                sort_order: Number(event.target.value) || 0,
              }))
            }
            fullWidth
          />
        </FormGrid>
      </Modal>

      <Modal
        isOpen={subModalOpen}
        onClose={() => setSubModalOpen(false)}
        title={
          editingSub ? t('admin:categories.editSubTitle') : t('admin:categories.createSubTitle')
        }
        footer={
          <>
            <Button variant="secondary" onClick={() => setSubModalOpen(false)}>
              {t('common:actions.cancel')}
            </Button>
            <Button
              variant="primary"
              loading={saveSubMutation.isPending}
              disabled={!subForm.name_en.trim() || !subForm.name_ar.trim()}
              onClick={() => saveSubMutation.mutate()}
            >
              {t('common:actions.save')}
            </Button>
          </>
        }
      >
        <FormGrid>
          <Input
            label={t('admin:categories.nameEn')}
            value={subForm.name_en}
            onChange={(event) => setSubForm((prev) => ({ ...prev, name_en: event.target.value }))}
            fullWidth
            required
          />
          <Input
            label={t('admin:categories.nameAr')}
            value={subForm.name_ar}
            onChange={(event) => setSubForm((prev) => ({ ...prev, name_ar: event.target.value }))}
            fullWidth
            required
          />
          <Select
            label={t('admin:categories.slaPolicy')}
            value={subForm.sla_policy_id}
            onChange={(event) =>
              setSubForm((prev) => ({ ...prev, sla_policy_id: event.target.value }))
            }
            options={slaOptions}
            hint={!editingSub ? t('admin:categories.inheritedSla') : undefined}
            fullWidth
          />
          <Input
            label={t('admin:categories.sortOrder')}
            type="number"
            value={String(subForm.sort_order)}
            onChange={(event) =>
              setSubForm((prev) => ({ ...prev, sort_order: Number(event.target.value) || 0 }))
            }
            fullWidth
          />
        </FormGrid>
      </Modal>
    </AppLayout>
  );
};

export default AdminCategoriesPage;
