import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
  Badge,
  Button,
  Group,
  Modal,
  MultiSelect,
  NumberInput,
  Stack,
  Switch,
  Text,
  TextInput,
  ThemeIcon,
} from '@mantine/core';
import { IconBuildingWarehouse, IconPlus } from '@tabler/icons-react';
import { AdvancedTable, ModalFooter, PageHeader, notify, useServerTable, type AdvancedColumn } from '@ema-platform/ui';
import {
  extractErrorMessage,
  useCreatePickupOfficeMutation,
  useGetPickupOfficesQuery,
  useUpdatePickupOfficeMutation,
  type PickupOffice,
} from '@ema-platform/api';
import { LICENSE_PERMISSIONS, RequirePermission } from '@ema-platform/auth';

const WEEKDAYS = [
  { value: '0', label: 'Sun' },
  { value: '1', label: 'Mon' },
  { value: '2', label: 'Tue' },
  { value: '3', label: 'Wed' },
  { value: '4', label: 'Thu' },
  { value: '5', label: 'Fri' },
  { value: '6', label: 'Sat' },
];

type OfficeDraft = {
  name: string;
  address: string;
  workingDays: string[];
  startTime: string;
  endTime: string;
  slotDurationMinutes: number;
  maxApplicantsPerSlot: number;
  rescheduleMinNoticeHours: number;
  isActive: boolean;
};

const EMPTY_DRAFT: OfficeDraft = {
  name: '',
  address: '',
  workingDays: ['1', '2', '3', '4', '5'],
  startTime: '08:30',
  endTime: '17:00',
  slotDurationMinutes: 30,
  maxApplicantsPerSlot: 10,
  rescheduleMinNoticeHours: 24,
  isActive: true,
};

function toDraft(office: PickupOffice): OfficeDraft {
  return {
    name: office.name,
    address: office.address ?? '',
    workingDays: office.workingDays.map(String),
    startTime: office.startTime,
    endTime: office.endTime,
    slotDurationMinutes: office.slotDurationMinutes,
    maxApplicantsPerSlot: office.maxApplicantsPerSlot,
    rescheduleMinNoticeHours: office.rescheduleMinNoticeHours,
    isActive: office.isActive,
  };
}

/**
 * Office/location, working hours, slot capacity and reschedule cutoff — the
 * configuration `PickupService.availableSlots` computes real slots from
 * (spec §20). Holiday management lives here too, one office at a time,
 * rather than a separate page — a holiday has no meaning without an office.
 */
export function PickupOfficesPage() {
  const { t } = useTranslation();
  const { data: offices, isFetching, refetch } = useGetPickupOfficesQuery();
  const [createOffice, { isLoading: creating }] = useCreatePickupOfficeMutation();
  const [updateOffice, { isLoading: updating }] = useUpdatePickupOfficeMutation();
  const { setPageIndex, pageSize, setPageSize, paginate } = useServerTable();

  const [editing, setEditing] = useState<PickupOffice | null>(null);
  const [creatingNew, setCreatingNew] = useState(false);
  const [draft, setDraft] = useState<OfficeDraft>(EMPTY_DRAFT);

  const page = paginate(offices ?? []);

  function openEdit(office: PickupOffice) {
    setEditing(office);
    setDraft(toDraft(office));
  }

  function openCreate() {
    setCreatingNew(true);
    setDraft(EMPTY_DRAFT);
  }

  function close() {
    setEditing(null);
    setCreatingNew(false);
  }

  async function save() {
    const body = {
      name: draft.name,
      address: draft.address || undefined,
      workingDays: draft.workingDays.map(Number),
      startTime: draft.startTime,
      endTime: draft.endTime,
      slotDurationMinutes: draft.slotDurationMinutes,
      maxApplicantsPerSlot: draft.maxApplicantsPerSlot,
      rescheduleMinNoticeHours: draft.rescheduleMinNoticeHours,
      isActive: draft.isActive,
    };
    try {
      if (editing) {
        await updateOffice({ id: editing.id, ...body }).unwrap();
      } else {
        await createOffice(body).unwrap();
      }
      notify.success(t('pickupOffices.saved', 'Office saved'));
      close();
    } catch (err) {
      notify.error(extractErrorMessage(err), t('pickupOffices.saveFailed', 'Could not save'));
    }
  }

  const columns: AdvancedColumn<PickupOffice>[] = [
    {
      header: t('pickupOffices.columns.name', 'Office'),
      cell: ({ row }) => (
        <>
          <Text size="sm" fw={600}>
            {row.original.name}
          </Text>
          <Text size="xs" c="dimmed">
            {row.original.address ?? '—'}
          </Text>
        </>
      ),
    },
    {
      header: t('pickupOffices.columns.hours', 'Working hours'),
      cell: ({ row }) => (
        <Text size="sm">
          {row.original.startTime}–{row.original.endTime}
        </Text>
      ),
    },
    {
      header: t('pickupOffices.columns.capacity', 'Capacity / slot'),
      cell: ({ row }) => (
        <Text size="sm">
          {row.original.maxApplicantsPerSlot} · {row.original.slotDurationMinutes}min
        </Text>
      ),
    },
    {
      header: t('pickupOffices.columns.status', 'Status'),
      cell: ({ row }) => (
        <Badge size="sm" color={row.original.isActive ? 'teal' : 'gray'} variant="light">
          {row.original.isActive
            ? t('pickupOffices.active', 'Active')
            : t('pickupOffices.inactive', 'Inactive')}
        </Badge>
      ),
    },
    {
      header: '',
      align: 'right',
      cell: ({ row }) => (
        <RequirePermission anyOf={[LICENSE_PERMISSIONS.CONFIGURE_PICKUP_OFFICES]} hideOnly>
          <Button size="xs" variant="light" onClick={() => openEdit(row.original)}>
            {t('pickupOffices.edit', 'Edit')}
          </Button>
        </RequirePermission>
      ),
    },
  ];

  return (
    <Stack gap="lg">
      <PageHeader
        title={t('pickupOffices.title', 'Pickup Offices')}
        subtitle={t(
          'pickupOffices.subtitle',
          'Where applicants collect printed documents, and how many can be booked into each slot.',
        )}
        noMargin
        action={
          <Group gap="sm">
            <ThemeIcon size="xl" radius="md" variant="light">
              <IconBuildingWarehouse size={22} />
            </ThemeIcon>
            <RequirePermission anyOf={[LICENSE_PERMISSIONS.CONFIGURE_PICKUP_OFFICES]} hideOnly>
              <Button leftSection={<IconPlus size={16} />} onClick={openCreate}>
                {t('pickupOffices.new', 'New office')}
              </Button>
            </RequirePermission>
          </Group>
        }
      />

      <AdvancedTable
        tableName="pickup-offices"
        columns={columns}
        data={page.rows}
        itemCount={page.itemCount}
        pageIndex={page.pageIndex}
        onPageChange={setPageIndex}
        pageSize={pageSize}
        onPageSizeChange={setPageSize}
        refresh={refetch}
        isLoading={isFetching}
      />

      <Modal
        opened={Boolean(editing) || creatingNew}
        onClose={close}
        title={editing ? t('pickupOffices.editTitle', 'Edit office') : t('pickupOffices.new', 'New office')}
      >
        <Stack>
          <TextInput
            label={t('pickupOffices.form.name', 'Name')}
            value={draft.name}
            onChange={(e) => setDraft((d) => ({ ...d, name: e.currentTarget.value }))}
            withAsterisk
          />
          <TextInput
            label={t('pickupOffices.form.address', 'Address')}
            value={draft.address}
            onChange={(e) => setDraft((d) => ({ ...d, address: e.currentTarget.value }))}
          />
          <MultiSelect
            label={t('pickupOffices.form.workingDays', 'Working days')}
            data={WEEKDAYS}
            value={draft.workingDays}
            onChange={(v) => setDraft((d) => ({ ...d, workingDays: v }))}
          />
          <Group grow>
            <TextInput
              label={t('pickupOffices.form.startTime', 'Start time')}
              placeholder="08:30"
              value={draft.startTime}
              onChange={(e) => setDraft((d) => ({ ...d, startTime: e.currentTarget.value }))}
            />
            <TextInput
              label={t('pickupOffices.form.endTime', 'End time')}
              placeholder="17:00"
              value={draft.endTime}
              onChange={(e) => setDraft((d) => ({ ...d, endTime: e.currentTarget.value }))}
            />
          </Group>
          <Group grow>
            <NumberInput
              label={t('pickupOffices.form.slotDuration', 'Slot length (min)')}
              min={5}
              value={draft.slotDurationMinutes}
              onChange={(v) =>
                setDraft((d) => ({ ...d, slotDurationMinutes: Number(v) || d.slotDurationMinutes }))
              }
            />
            <NumberInput
              label={t('pickupOffices.form.capacity', 'Max per slot')}
              min={1}
              value={draft.maxApplicantsPerSlot}
              onChange={(v) =>
                setDraft((d) => ({ ...d, maxApplicantsPerSlot: Number(v) || d.maxApplicantsPerSlot }))
              }
            />
          </Group>
          <NumberInput
            label={t('pickupOffices.form.rescheduleCutoff', 'Reschedule minimum notice (hours)')}
            min={0}
            value={draft.rescheduleMinNoticeHours}
            onChange={(v) =>
              setDraft((d) => ({
                ...d,
                rescheduleMinNoticeHours: Number(v) || d.rescheduleMinNoticeHours,
              }))
            }
          />
          <Switch
            label={t('pickupOffices.form.active', 'Active')}
            checked={draft.isActive}
            onChange={(e) => setDraft((d) => ({ ...d, isActive: e.currentTarget.checked }))}
          />

          <ModalFooter>
            <Button variant="default" onClick={close}>
              {t('common.cancel', 'Cancel')}
            </Button>
            <Button loading={creating || updating} disabled={!draft.name.trim()} onClick={save}>
              {t('common.save', 'Save')}
            </Button>
          </ModalFooter>
        </Stack>
      </Modal>
    </Stack>
  );
}

export default PickupOfficesPage;
