import { useEffect, useMemo } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useParams, useNavigate, Link } from 'react-router';
import { ChevronRightIcon } from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import type { PatientRecord } from '../types';
import PersianDateInput from '../components/ui/PersianDateInput';
import SearchableSelect from '../components/ui/SearchableSelect';
import { numericField } from '../lib/forms';
import BackButton from '../components/ui/BackButton';
import { iranNationalCodeSchema, iranMobileSchema, unixToIso } from '../lib/utils';
import { useRecordNumberSettings } from '../hooks/useRecordNumberSettings';
import TourButton from '../components/ui/TourButton';

const REFERRAL_OPTIONS = ['اینستاگرام', 'معرفی دوستان و آشنایان', 'جستجوی اینترنتی', 'تابلو مطب', 'سایر'];

const schema = z.object({
  name:            z.string().min(1, 'نام و نام خانوادگی الزامی است'),
  // الزامی‌بودنش شرطی است: با الگوی فعال، سرور شماره را می‌سازد و این فیلد اصلاً
  // فرستاده نمی‌شود. اعتبارسنجیِ شرطی در `superRefine` پایین‌تر است.
  record_number:   z.string(),
  gender:          z.enum(['male', 'female'], { errorMap: () => ({ message: 'جنسیت را انتخاب کنید' }) }),
  national_code:   iranNationalCodeSchema,
  mobile:          iranMobileSchema,
  birth_date:      z.string().optional(),
  referral_source: z.string().optional(),
  description:     z.string().optional(),
});
type Form = z.infer<typeof schema>;

const toEpoch = (iso?: string) => (iso ? Math.floor(new Date(iso).getTime() / 1000) : null);
const fromEpoch = (ts?: number | null) => unixToIso(ts);

/** تشکیل/ویرایش پرونده — patient record create & edit form (Figma "تشکیل پرونده"). */
export default function PatientRecordFormPage() {
  const { uuid } = useParams<{ uuid: string }>();
  const isEdit = !!uuid;
  const navigate = useNavigate();
  const qc = useQueryClient();

  const { settings } = useRecordNumberSettings();
  /** الگو روشن است ⇒ شماره را سرور می‌سازد. */
  const autoNumbered = !!settings?.enabled;
  /** ورود دستی: وقتی الگویی نیست، یا کاربر صاحب مجموعه است (سرور هم همین را می‌سنجد). */
  const manualAllowed = !autoNumbered || !!settings?.can_edit;

  const formSchema = useMemo(
    () => schema.superRefine((v, ctx) => {
      // فقط وقتی شماره دستی است الزامی می‌ماند؛ وگرنه کاربر با فیلدی که نمی‌تواند
      // پرش کند پشت فرمِ قفل‌شده می‌ماند.
      if (!autoNumbered && !(v.record_number ?? '').trim()) {
        ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['record_number'], message: 'شماره پرونده الزامی است' });
      }
    }),
    [autoNumbered],
  );

  const form = useForm<Form>({
    resolver: zodResolver(formSchema),
    defaultValues: { name: '', record_number: '', gender: undefined as any, national_code: '', mobile: '', birth_date: '', referral_source: '', description: '' },
  });

  const { data: recordData } = useQuery<ApiResponse<PatientRecord>>({
    queryKey: ['patient', uuid],
    queryFn: () => api.get(`/api/v1/patient/${uuid}`),
    enabled: isEdit,
  });

  useEffect(() => {
    const r = recordData?.data;
    if (!r) return;
    const p: any = r.profile ?? {};
    form.reset({
      name: r.user_name ?? '',
      record_number: r.record_number ?? '',
      gender: (p.gender as 'male' | 'female') ?? undefined,
      national_code: r.user_national_code ?? '',
      mobile: r.user_mobile ?? '',
      birth_date: fromEpoch(p.date_of_birth),
      referral_source: p.referral_source ?? '',
      description: p.description ?? '',
    });
  }, [recordData]); // eslint-disable-line react-hooks/exhaustive-deps

  const save = useMutation({
    mutationFn: async (d: Form) => {
      const profilePayload = {
        gender: d.gender,
        date_of_birth: toEpoch(d.birth_date),
        referral_source: d.referral_source || null,
        description: d.description || null,
      };
      // شمارهٔ پرونده فقط وقتی فرستاده می‌شود که ورود دستی مجاز باشد؛ وگرنه سرور
      // ۴۰۳ می‌دهد و سرورست که شماره را از الگو می‌سازد.
      const numberPayload = manualAllowed ? { record_number: d.record_number ?? '' } : {};

      if (isEdit) {
        return api.patch(`/api/v1/patient/${uuid}`, {
          name: d.name, national_code: d.national_code, mobile: d.mobile, ...numberPayload, ...profilePayload,
        });
      }
      // create: POST creates the record + identity, then PATCH applies the profile demographics
      const created = await api.post<ApiResponse<PatientRecord>>('/api/v1/patient', {
        name: d.name, mobile: d.mobile, national_code: d.national_code, ...numberPayload,
      });
      const newUuid = (created as any)?.data?.uuid;
      if (newUuid) await api.patch(`/api/v1/patient/${newUuid}`, profilePayload);
      return created;
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['patients'] });
      toast.success(isEdit ? 'پرونده ویرایش شد' : 'پرونده تشکیل شد');
      navigate('/admin/patients');
    },
    onError: (e: any) => toast.error(e.message),
  });

  const Field = ({ label, required, error, children }: { label: string; required?: boolean; error?: string; children: React.ReactNode }) => (
    <div>
      <label className="field-label">{label} {required && <span style={{ color: 'var(--danger)' }}>*</span>}</label>
      {children}
      {error && <span className="field-error">{error}</span>}
    </div>
  );

  return (
    <div className="fade-in" style={{ maxWidth: 1000, margin: '0 auto' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18 }}>
        <BackButton fallback="/admin/patients" />
        <div style={{ fontSize: 14, color: 'var(--text-3)', display: 'flex', alignItems: 'center', gap: 4 }} data-tour="page-title">
          پرونده › <b style={{ color: 'var(--text)' }}>{isEdit ? 'ویرایش پرونده' : 'تشکیل پرونده'}</b>
          <TourButton tourId="patient-record-form" ready />
        </div>
      </div>

      <form onSubmit={form.handleSubmit((d) => save.mutate(d))} data-tour="record-form"
        style={{ background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-lg)', padding: 24 }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 18 }}>
          <Field label="نام و نام خانوادگی مراجعه کننده" required error={form.formState.errors.name?.message}>
            <div className="field"><input {...form.register('name')} placeholder="نام و نام خانوادگی را وارد نمایید" /></div>
          </Field>
          <Field
            label="شماره پرونده"
            required={!autoNumbered}
            error={form.formState.errors.record_number?.message}
          >
            {manualAllowed ? (
              <div className="field">
                <input
                  {...form.register('record_number')}
                  placeholder={autoNumbered ? (settings?.next_preview ?? 'شماره پرونده') : 'شماره پرونده'}
                />
              </div>
            ) : (
              <div className="field" style={{ opacity: 0.7 }}>
                <input value={isEdit ? (recordData?.data?.record_number ?? '') : (settings?.next_preview ?? '')} readOnly dir="ltr" />
              </div>
            )}
            {autoNumbered && (
              <span style={{ fontSize: 11.5, color: 'var(--text-3)', display: 'block', marginTop: 4 }}>
                {manualAllowed
                  ? `خالی بماند تا از الگو ساخته شود (شمارهٔ بعدی: ${settings?.next_preview ?? '—'})`
                  : 'شماره از الگوی مجموعه ساخته می‌شود'}
              </span>
            )}
          </Field>
          <Field label="جنسیت" required error={form.formState.errors.gender?.message}>
            <SearchableSelect
              inputId="patient-gender-select"
              options={[{ value: 'female', label: 'زن' }, { value: 'male', label: 'مرد' }]}
              value={form.watch('gender') ?? null}
              onChange={(v) => form.setValue('gender', v as Form['gender'], { shouldValidate: true, shouldDirty: true })}
              placeholder="انتخاب..."
              height={38}
            />
          </Field>
          <Field label="کد ملی" required error={form.formState.errors.national_code?.message}>
            <div className="field"><input {...numericField(form.register('national_code'), 10)} placeholder="کد ملی را وارد نمایید" /></div>
          </Field>
          <Field label="شماره تماس" required error={form.formState.errors.mobile?.message}>
            <div className="field"><input {...numericField(form.register('mobile'), 11)} placeholder="شماره تماس را وارد نمایید" /></div>
          </Field>
          <Field label="تاریخ تولد">
            <PersianDateInput value={form.watch('birth_date') ?? ''} onChange={(v) => form.setValue('birth_date', v)} enableYearPicker />
          </Field>
          <Field label="نحوه آشنایی">
            <SearchableSelect
              options={REFERRAL_OPTIONS.map((o) => ({ value: o, label: o }))}
              value={form.watch('referral_source') || null}
              onChange={(v) => form.setValue('referral_source', v ? String(v) : '', { shouldDirty: true })}
              placeholder="انتخاب کنید..."
              isClearable
              height={38}
            />
          </Field>
        </div>

        <div style={{ marginTop: 18 }}>
          <Field label="توضیحات">
            <div className="field" style={{ height: 'auto' }}><textarea {...form.register('description')} rows={4} placeholder="توضیحات" style={{ width: '100%', border: 'none', background: 'transparent', fontFamily: 'inherit', resize: 'vertical' }} /></div>
          </Field>
        </div>

        <button type="submit" className="btn primary" style={{ marginTop: 22, height: 44, padding: '0 24px' }} disabled={save.isPending}>
          {save.isPending ? 'در حال ذخیره...' : 'ثبت اطلاعات'}
        </button>
      </form>
    </div>
  );
}
