'use client';
import { Suspense, useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useRouter } from 'next/navigation';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useSnackbar } from 'notistack';
import {
  Box,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControlLabel,
  Skeleton,
  Stack,
  Switch,
  Typography,
} from '@mui/material';
import { AppButton, AppLoading, RhfControlGroup, RhfTextField, StatusChip } from '@/components';
import type { StatusKind } from '@/components';
import {
  AdminDataTable,
  AdminEmptyState,
  AdminErrorState,
  AdminPageHeader,
  AdminPager,
  UserPicker,
  type AdminTableColumn,
} from '@/components/admin';
import { useAdminCapabilities, useAdminListState } from '@/hooks';
import { adminPartnerCenterPath } from '@/constants';
import { PARTNER_PAGE_SIZE } from '@/services/partnerCenter/constants';
import type { CenterOnboardingState, PartnerCenter, PartnerCenterInput } from '@/services/partnerCenter/types';
import type { AdminUserSummary } from '@/services/admin/types';
import { useUserLookup } from '@/services/admin';
import { usePartnerCenters, useCreatePartnerCenter, useUpdatePartnerCenter } from '@/services/partnerCenter';

/** No list-level filters today (the list is unfiltered) — `useAdminListState` still URL-syncs the page. */
type PartnersListFilters = Record<string, never>;
const EMPTY_FILTERS: PartnersListFilters = {};

/** State → semantic chip color. verified = green, pending = amber, suspended = red, draft = neutral. */
export const CENTER_STATE_KIND: Record<CenterOnboardingState, StatusKind> = {
  verified: 'verified',
  pending_verification: 'pending',
  suspended: 'rejected',
  draft: 'neutral',
};

/**
 * Partner-center admin list (f15) — the licensed sponsoring centers (پروانه تأسیس + مسئول فنی + نماد
 * اعتماد الکترونیکی) that may be the merchant-of-record. Each row shows whether it issues invoices, its
 * sponsored-nurse count, and its onboarding state; a row opens the center detail. Admins with
 * `canManagePartners` may create a new center (inactive until verified). The full IBAN is write-then-masked —
 * it is only ever entered here, never displayed (the list carries no IBAN at all).
 */
export default function AdminPartnersPage() {
  return (
    <Suspense fallback={<AppLoading />}>
      <AdminPartnersPageInner />
    </Suspense>
  );
}

function AdminPartnersPageInner() {
  const t = useTranslations('admin');
  const locale = useLocale();
  const router = useRouter();
  const caps = useAdminCapabilities();
  const [creating, setCreating] = useState(false);

  const listState = useAdminListState<PartnersListFilters>({
    parse: () => EMPTY_FILTERS,
    serialize: () => ({}),
    empty: EMPTY_FILTERS,
  });
  const page = listState.page;

  const centers = usePartnerCenters({}, page);
  const items = centers.data?.items ?? [];
  const total = centers.data?.total ?? 0;
  const pageCount = Math.max(1, Math.ceil(total / PARTNER_PAGE_SIZE));
  const from = items.length === 0 ? 0 : (page - 1) * PARTNER_PAGE_SIZE + 1;
  const to = (page - 1) * PARTNER_PAGE_SIZE + items.length;

  const columns: AdminTableColumn<PartnerCenter>[] = [
    { key: 'name', header: t('partner_col_name'), render: (c) => c.name },
    { key: 'mor', header: t('partner_col_mor'), render: (c) => t(c.isMerchantOfRecord ? 'yes' : 'no') },
    { key: 'nurses', header: t('partner_col_nurses'), render: (c) => c.sponsoredNurseCount },
    {
      key: 'state',
      header: t('partner_col_state'),
      render: (c) => <StatusChip status={CENTER_STATE_KIND[c.onboardingState]} label={t(`center_state_${c.onboardingState}`)} />,
    },
  ];

  return (
    <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      <AdminPageHeader
        title={t('partner_title')}
        subtitle={t('partner_subtitle')}
        actions={
          caps.canManagePartners ? (
            <AppButton variant="contained" color="primary" startIcon="add" onClick={() => setCreating(true)}>
              {t('partner_create')}
            </AppButton>
          ) : undefined
        }
      />

      {centers.isLoading ? (
        <Skeleton variant="rounded" height={220} />
      ) : centers.isError ? (
        <AdminErrorState message={t('error_generic')} retryLabel={t('retry')} onRetry={() => centers.refetch()} />
      ) : items.length === 0 ? (
        <AdminEmptyState icon="partners" title={t('partner_empty')} />
      ) : (
        <AdminDataTable
          columns={columns}
          rows={items}
          getRowKey={(c) => c.id}
          ariaLabel={t('partner_title')}
          onRowClick={(c) => router.push(`/${locale}${adminPartnerCenterPath(c.id)}`)}
          footer={total > 0 ? t('showing_range', { from, to, total }) : undefined}
        />
      )}

      <AdminPager
        page={page}
        pageCount={pageCount}
        onPrev={() => listState.goToPage(Math.max(1, page - 1))}
        onNext={() => listState.goToPage(Math.min(pageCount, page + 1))}
        prevLabel={t('prev_page')}
        nextLabel={t('next_page')}
        indicator={t('page_indicator', { page, total: pageCount })}
      />

      {creating ? <PartnerCenterFormDialog center={null} onClose={() => setCreating(false)} /> : null}
    </Box>
  );
}

/** The editable slice of `PartnerCenterInput`, kept as strings for controlled text/number inputs — except
 * `adminUser`, the resolved picker selection (3.2), never a hand-typed id. `undefined` = untouched (the
 * edit-mode existing admin, once resolved, still shows); `null` = the admin explicitly cleared the field. */
interface CenterFormState {
  name: string;
  legalEntityType: string;
  mohEstablishmentPermitNo: string;
  technicalDirectorLicenseNo: string;
  enamadCode: string;
  settlementIban: string;
  isMerchantOfRecord: boolean;
  commissionRate: string;
  adminUser: AdminUserSummary | null | undefined;
}

function initialForm(center: PartnerCenter | null): CenterFormState {
  return {
    name: center?.name ?? '',
    legalEntityType: center?.legalEntityType ?? '',
    mohEstablishmentPermitNo: center?.mohEstablishmentPermitNo ?? '',
    technicalDirectorLicenseNo: center?.technicalDirectorLicenseNo ?? '',
    enamadCode: center?.enamadCode ?? '',
    // Write-then-masked: always blank on open. On edit, a blank IBAN keeps the existing masked value.
    settlementIban: '',
    isMerchantOfRecord: center?.isMerchantOfRecord ?? false,
    commissionRate: center != null ? String(center.commissionRate) : '',
    adminUser: undefined,
  };
}

/**
 * The create/edit dialog for a partner center — shared by the list (create, `center=null`) and the detail
 * (edit, `center` prefilled). `settlementIban` is write-then-masked: the field is always blank on open and a
 * blank submit on edit keeps the stored masked value. Validates name + permit non-empty, `commissionRate ∈
 * [0, 1)`, and (create only) an IBAN when the center is merchant-of-record.
 */
export function PartnerCenterFormDialog({ center, onClose }: { center: PartnerCenter | null; onClose: () => void }) {
  const t = useTranslations('admin');
  const { enqueueSnackbar } = useSnackbar();
  const isEdit = center != null;
  const create = useCreatePartnerCenter();
  const update = useUpdatePartnerCenter(center?.id ?? 0);
  const mutation = isEdit ? update : create;

  const form = useForm<CenterFormState>({ mode: 'onTouched', defaultValues: initialForm(center) });
  const { control, handleSubmit, formState } = form;
  const isMerchantOfRecord = useWatch({ control, name: 'isMerchantOfRecord' });
  const adminUser = useWatch({ control, name: 'adminUser' });

  // Edit mode: the center already has an adminUserId (a plain number) — resolve it to a name so the picker
  // opens pre-filled with a person, never a bare id (3.2). Derived in render (never synced into form state):
  // once the admin actually picks someone, the form value wins over the resolved existing one.
  const existingAdminId = center?.adminUserId ?? null;
  const existingAdminLookup = useUserLookup(existingAdminId != null ? [existingAdminId] : []);
  const resolvedExistingAdmin = existingAdminId != null ? (existingAdminLookup.data?.get(existingAdminId) ?? null) : null;
  const displayedAdminUser = adminUser !== undefined ? adminUser : resolvedExistingAdmin;

  const onSave = (values: CenterFormState) => {
    const input: PartnerCenterInput = {
      name: values.name.trim(),
      legalEntityType: values.legalEntityType.trim(),
      mohEstablishmentPermitNo: values.mohEstablishmentPermitNo.trim(),
      technicalDirectorLicenseNo: values.technicalDirectorLicenseNo.trim() || null,
      enamadCode: values.enamadCode.trim() || null,
      settlementIban: values.settlementIban.trim() || null,
      isMerchantOfRecord: values.isMerchantOfRecord,
      commissionRate: Number(values.commissionRate),
      adminUserId: displayedAdminUser?.id ?? null,
    };
    mutation.mutate(input, {
      onSuccess: () => {
        enqueueSnackbar(t('partner_saved'), { variant: 'success' });
        onClose();
      },
    });
  };

  return (
    <Dialog open onClose={mutation.isPending ? undefined : onClose} fullWidth maxWidth="sm">
      <DialogTitle sx={{ fontWeight: 800 }}>{isEdit ? t('partner_edit') : t('partner_create')}</DialogTitle>
      <FormProvider {...form}>
        <DialogContent>
          {/* A real <form> so Enter submits from any field; the footer button (outside DialogContent)
              calls the same handler directly rather than relying on cross-element form association. */}
          <Stack component="form" noValidate onSubmit={handleSubmit(onSave)} sx={{ gap: 2, mt: 1 }}>
            <RhfTextField<CenterFormState>
              name="name"
              label={t('partner_name')}
              rules={{ validate: (value) => String(value ?? '').trim() !== '' }}
            />
            <RhfTextField<CenterFormState> name="legalEntityType" label={t('partner_legal_type')} />
            <RhfTextField<CenterFormState>
              name="mohEstablishmentPermitNo"
              label={t('partner_permit')}
              rules={{ validate: (value) => String(value ?? '').trim() !== '' }}
            />
            <RhfTextField<CenterFormState>
              name="technicalDirectorLicenseNo"
              label={t('partner_tech_director_license')}
            />
            <RhfTextField<CenterFormState> name="enamadCode" label={t('partner_enamad')} />
            <RhfTextField<CenterFormState>
              name="settlementIban"
              label={t('partner_iban')}
              helperText={t('partner_iban_write_hint')}
              placeholder={center?.settlementIbanMasked ?? undefined}
              // On edit a blank IBAN keeps the stored value; on create an MoR center must supply one.
              rules={{ validate: (value) => !isMerchantOfRecord || isEdit || String(value ?? '').trim() !== '' }}
              slotProps={{ htmlInput: { dir: 'ltr' } }}
            />
            <Box>
              <RhfControlGroup<CenterFormState> name="isMerchantOfRecord">
                {({ field }) => (
                  <FormControlLabel
                    control={
                      <Switch
                        checked={Boolean(field.value)}
                        onChange={(event) => field.onChange(event.target.checked)}
                      />
                    }
                    label={t('partner_is_mor')}
                  />
                )}
              </RhfControlGroup>
              <Typography variant="caption" sx={{ display: 'block', color: 'text.secondary' }}>
                {t('partner_is_mor_hint')}
              </Typography>
            </Box>
            <RhfTextField<CenterFormState>
              name="commissionRate"
              type="number"
              label={t('partner_commission')}
              rules={{
                validate: (value) => {
                  const raw = String(value ?? '').trim();
                  const rate = Number(raw);
                  return raw !== '' && Number.isFinite(rate) && rate >= 0 && rate < 1;
                },
              }}
              slotProps={{ htmlInput: { min: 0, max: 0.999, step: 0.01 } }}
            />
            <RhfControlGroup<CenterFormState> name="adminUser">
              {({ field }) => (
                <UserPicker
                  value={displayedAdminUser}
                  onChange={field.onChange}
                  label={t('partner_admin_user')}
                  placeholder={t('user_picker_search_ph')}
                  noOptionsText={t('user_picker_no_options')}
                  loadingText={t('user_picker_loading')}
                />
              )}
            </RhfControlGroup>
          </Stack>
        </DialogContent>
        <DialogActions sx={{ px: 3, pb: 2 }}>
          <AppButton variant="text" color="inherit" onClick={onClose} disabled={mutation.isPending}>
            {t('cancel')}
          </AppButton>
          <AppButton
            variant="contained"
            color="primary"
            onClick={handleSubmit(onSave)}
            disabled={!formState.isValid || mutation.isPending}
          >
            {mutation.isPending ? t('saving') : t('save')}
          </AppButton>
        </DialogActions>
      </FormProvider>
    </Dialog>
  );
}
