'use client';
import { useState } from 'react';
import { useLocale, useTranslations } from 'next-intl';
import { useParams, useRouter } from 'next/navigation';
import { useSnackbar } from 'notistack';
import {
  Checkbox,
  FormControlLabel,
  IconButton,
  Paper,
  Skeleton,
  Stack,
  Tab,
  Tabs,
  TextField,
  Typography,
} from '@mui/material';
import { AppButton, AppIcon, EmptyState, PatientHeader, VisitNoteCard } from '@/components';
import { ROUTES } from '@/constants';
import { formatShamsiDate } from '@/utils';
import { usePatient } from '@/services/patients';
import { birthDateToAge } from '@/services/patients/age';
import { useRecordAccess, usePatientCareRecord, usePatientHistory, useUpdateCareRecord } from '@/services/patientRecords';
import { CARE_RECORD_TABS } from '@/services/patientRecords/types';
import type {
  CareRecordTab,
  CareTask,
  FamilyCareRecord,
  Medication,
  RoutineItem,
} from '@/services/patientRecords/types';

/**
 * E2 — Patient care-record viewer (پروندهٔ مراقبت). The **family-owned, patient-scoped** record with four
 * tabs: داروها / روتین / سوابق / وظایف. The customer owns and edits medications/routine/tasks; the **سوابق**
 * (nurse visit notes) are read-only to everyone. A persistent ownership banner states the record belongs to
 * the family. The clinical-access check gates the whole screen (a `403` → a clear, non-leaking access-denied
 * card — never partial clinical data).
 */
export default function PatientRecordPage() {
  const t = useTranslations('records');
  // Shared enum labels are reused from the onboarding/patients namespaces — never re-keyed.
  const to = useTranslations('onboarding');
  const tp = useTranslations('patients');

  const params = useParams<{ id: string }>();
  const rawId = Number(params.id);
  const patientId = Number.isInteger(rawId) && rawId > 0 ? rawId : -1;

  const access = useRecordAccess(patientId);
  const canView = access.data?.canView ?? false;
  const patient = usePatient(patientId, { enabled: canView });

  const [tab, setTab] = useState<CareRecordTab>('medications');

  if (access.isLoading) return <RecordSkeleton />;

  // Access-denied — a clear, non-leaking card (never any clinical data).
  if (access.data && !access.data.canView) {
    return (
      <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%' }}>
        <EmptyState icon="lock" title={t('access_denied_title')} body={t('access_denied_body')} />
        <BackToPatients />
      </Stack>
    );
  }

  if (patient.isLoading) return <RecordSkeleton />;

  if (patient.isError || !patient.data) {
    return (
      <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%' }}>
        <EmptyState title={t('not_found_title')} body={t('not_found_body')} />
        <BackToPatients />
      </Stack>
    );
  }

  const p = patient.data;
  const age = birthDateToAge(p.birthDate);

  return (
    <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%' }}>
      <PatientHeader
        displayName={p.displayName}
        relationLabel={p.relation ? to(`relation_${p.relation}`) : undefined}
        genderLabel={to(`gender_${p.gender}`)}
        ageLabel={age == null ? undefined : tp('age_years', { age })}
        conditionLabels={p.conditions.map((code) => to(`condition_${code}`))}
        noConditionsLabel={tp('conditions_none')}
      />

      <Paper
        elevation={0}
        sx={{ p: 2, borderRadius: 2, backgroundColor: 'var(--bal-primary-soft)', display: 'flex', gap: 1, alignItems: 'center' }}
      >
        <AppIcon icon="family" size={22} color="var(--bal-primary)" />
        <Typography variant="body2" sx={{ color: 'var(--bal-primary)', fontWeight: 500 }}>
          {t('ownership_banner')}
        </Typography>
      </Paper>

      <Tabs
        value={tab}
        onChange={(_, next: CareRecordTab) => setTab(next)}
        variant="scrollable"
        scrollButtons="auto"
        allowScrollButtonsMobile
        sx={{ borderBottom: 1, borderColor: 'divider' }}
      >
        {CARE_RECORD_TABS.map((value) => (
          <Tab key={value} value={value} label={t(`tab_${value}`)} sx={{ textTransform: 'none', fontWeight: 700 }} />
        ))}
      </Tabs>

      {tab === 'history' ? (
        <HistoryTab patientId={patientId} />
      ) : (
        <EditableTabs patientId={patientId} tab={tab} canEdit={access.data?.canEdit ?? false} />
      )}
    </Stack>
  );
}

/** The three customer-editable tabs (medications/routine/tasks) share one record read + one save mutation. */
function EditableTabs({ patientId, tab, canEdit }: { patientId: number; tab: CareRecordTab; canEdit: boolean }) {
  const t = useTranslations('records');
  const { enqueueSnackbar } = useSnackbar();
  const record = usePatientCareRecord(patientId);
  const update = useUpdateCareRecord(patientId);

  if (record.isLoading) {
    return (
      <Stack sx={{ gap: 1.5 }}>
        <Skeleton variant="rounded" height={72} />
        <Skeleton variant="rounded" height={72} />
      </Stack>
    );
  }
  if (record.isError || !record.data) {
    return (
      <Typography variant="body2" sx={{ color: 'text.secondary' }}>
        {t('load_error')}
      </Typography>
    );
  }

  const data = record.data;
  const save = (patch: Partial<Pick<FamilyCareRecord, 'medications' | 'routine' | 'tasks'>>, onDone: () => void) => {
    update.mutate(patch, {
      onSuccess: () => {
        enqueueSnackbar(t('saved'), { variant: 'success' });
        onDone();
      },
      onError: () => enqueueSnackbar(t('save_error'), { variant: 'error' }),
    });
  };

  if (tab === 'medications') {
    return <MedicationsTab data={data.medications} canEdit={canEdit} saving={update.isPending} onSave={(meds, done) => save({ medications: meds }, done)} />;
  }
  if (tab === 'routine') {
    return <RoutineTab data={data.routine} canEdit={canEdit} saving={update.isPending} onSave={(items, done) => save({ routine: items }, done)} />;
  }
  return <TasksTab data={data.tasks} canEdit={canEdit} saving={update.isPending} onSave={(tasks, done) => save({ tasks }, done)} />;
}

// ── Medications ───────────────────────────────────────────────────────────────────────────────────────────
function MedicationsTab({
  data,
  canEdit,
  saving,
  onSave,
}: {
  data: Medication[];
  canEdit: boolean;
  saving: boolean;
  onSave: (medications: Medication[], onDone: () => void) => void;
}) {
  const t = useTranslations('records');
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState<Medication[]>(data);

  const startEdit = () => {
    setDraft(data.map((m) => ({ ...m })));
    setEditing(true);
  };
  const update = (id: string, patch: Partial<Medication>) => setDraft((d) => d.map((m) => (m.id === id ? { ...m, ...patch } : m)));
  const remove = (id: string) => setDraft((d) => d.filter((m) => m.id !== id));
  const add = () => setDraft((d) => [...d, { id: `new-${d.length}-${Date.now()}`, name: '', dosage: null, frequency: '', timingNote: null }]);
  const canSave = draft.every((m) => m.name.trim().length > 0);

  if (!editing) {
    return (
      <SectionShell canEdit={canEdit} onEdit={startEdit} empty={data.length === 0} emptyLabel={t('medications_empty')}>
        {data.map((m) => (
          <Paper key={m.id} elevation={0} sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
            <Stack direction="row" sx={{ alignItems: 'center', gap: 1 }}>
              <AppIcon icon="medication" size={20} color="var(--bal-primary)" />
              <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
                {m.name}
                {m.dosage ? ` — ${m.dosage}` : ''}
              </Typography>
            </Stack>
            {(m.frequency || m.timingNote) && (
              <Typography variant="body2" sx={{ color: 'text.secondary', mt: 0.5 }}>
                {[m.frequency, m.timingNote].filter(Boolean).join(' · ')}
              </Typography>
            )}
          </Paper>
        ))}
      </SectionShell>
    );
  }

  return (
    <Stack sx={{ gap: 1.5 }}>
      {draft.map((m) => (
        <Paper key={m.id} elevation={0} sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
          <Stack sx={{ gap: 1 }}>
            <Stack direction="row" sx={{ gap: 1 }}>
              <TextField label={t('med_name')} value={m.name} onChange={(e) => update(m.id, { name: e.target.value })} size="small" fullWidth required />
              <IconButton aria-label={t('remove')} onClick={() => remove(m.id)} size="small">
                <AppIcon icon="delete" size={20} color="var(--bal-error)" />
              </IconButton>
            </Stack>
            <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
              <TextField label={t('med_dosage')} value={m.dosage ?? ''} onChange={(e) => update(m.id, { dosage: e.target.value || null })} size="small" sx={{ flex: 1, minWidth: 120 }} />
              <TextField label={t('med_frequency')} value={m.frequency} onChange={(e) => update(m.id, { frequency: e.target.value })} size="small" sx={{ flex: 1, minWidth: 120 }} />
            </Stack>
            <TextField label={t('med_timing')} value={m.timingNote ?? ''} onChange={(e) => update(m.id, { timingNote: e.target.value || null })} size="small" fullWidth />
          </Stack>
        </Paper>
      ))}
      <EditActions
        onAdd={add}
        onCancel={() => setEditing(false)}
        onSave={() => onSave(draft, () => setEditing(false))}
        saving={saving}
        canSave={canSave}
      />
    </Stack>
  );
}

// ── Routine ───────────────────────────────────────────────────────────────────────────────────────────────
function RoutineTab({
  data,
  canEdit,
  saving,
  onSave,
}: {
  data: RoutineItem[];
  canEdit: boolean;
  saving: boolean;
  onSave: (routine: RoutineItem[], onDone: () => void) => void;
}) {
  const t = useTranslations('records');
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState<RoutineItem[]>(data);

  const startEdit = () => {
    setDraft(data.map((r) => ({ ...r })));
    setEditing(true);
  };
  const update = (id: string, patch: Partial<RoutineItem>) => setDraft((d) => d.map((r) => (r.id === id ? { ...r, ...patch } : r)));
  const remove = (id: string) => setDraft((d) => d.filter((r) => r.id !== id));
  const add = () => setDraft((d) => [...d, { id: `new-${d.length}-${Date.now()}`, label: '', timeOfDay: null, note: null }]);
  const canSave = draft.every((r) => r.label.trim().length > 0);

  if (!editing) {
    return (
      <SectionShell canEdit={canEdit} onEdit={startEdit} empty={data.length === 0} emptyLabel={t('routine_empty')}>
        {data.map((r) => (
          <Paper key={r.id} elevation={0} sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
            <Stack direction="row" sx={{ alignItems: 'center', gap: 1 }}>
              <AppIcon icon="routine" size={20} color="var(--bal-primary)" />
              <Typography variant="subtitle2" sx={{ fontWeight: 700 }}>
                {r.label}
                {r.timeOfDay ? ` — ${r.timeOfDay}` : ''}
              </Typography>
            </Stack>
            {r.note ? (
              <Typography variant="body2" sx={{ color: 'text.secondary', mt: 0.5 }}>
                {r.note}
              </Typography>
            ) : null}
          </Paper>
        ))}
      </SectionShell>
    );
  }

  return (
    <Stack sx={{ gap: 1.5 }}>
      {draft.map((r) => (
        <Paper key={r.id} elevation={0} sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
          <Stack sx={{ gap: 1 }}>
            <Stack direction="row" sx={{ gap: 1 }}>
              <TextField label={t('routine_label')} value={r.label} onChange={(e) => update(r.id, { label: e.target.value })} size="small" fullWidth required />
              <IconButton aria-label={t('remove')} onClick={() => remove(r.id)} size="small">
                <AppIcon icon="delete" size={20} color="var(--bal-error)" />
              </IconButton>
            </Stack>
            <Stack direction="row" sx={{ gap: 1, flexWrap: 'wrap' }}>
              <TextField label={t('routine_time')} value={r.timeOfDay ?? ''} onChange={(e) => update(r.id, { timeOfDay: e.target.value || null })} size="small" sx={{ flex: 1, minWidth: 120 }} />
              <TextField label={t('routine_note')} value={r.note ?? ''} onChange={(e) => update(r.id, { note: e.target.value || null })} size="small" sx={{ flex: 2, minWidth: 120 }} />
            </Stack>
          </Stack>
        </Paper>
      ))}
      <EditActions onAdd={add} onCancel={() => setEditing(false)} onSave={() => onSave(draft, () => setEditing(false))} saving={saving} canSave={canSave} />
    </Stack>
  );
}

// ── Tasks ─────────────────────────────────────────────────────────────────────────────────────────────────
function TasksTab({
  data,
  canEdit,
  saving,
  onSave,
}: {
  data: CareTask[];
  canEdit: boolean;
  saving: boolean;
  onSave: (tasks: CareTask[], onDone: () => void) => void;
}) {
  const t = useTranslations('records');
  const [editing, setEditing] = useState(false);
  const [draft, setDraft] = useState<CareTask[]>(data);

  const startEdit = () => {
    setDraft(data.map((task) => ({ ...task })));
    setEditing(true);
  };
  const update = (id: string, patch: Partial<CareTask>) => setDraft((d) => d.map((task) => (task.id === id ? { ...task, ...patch } : task)));
  const remove = (id: string) => setDraft((d) => d.filter((task) => task.id !== id));
  const add = () => setDraft((d) => [...d, { id: `new-${d.length}-${Date.now()}`, label: '', done: false }]);
  const canSave = draft.every((task) => task.label.trim().length > 0);

  if (!editing) {
    return (
      <SectionShell canEdit={canEdit} onEdit={startEdit} empty={data.length === 0} emptyLabel={t('tasks_empty')}>
        {data.map((task) => (
          <Paper key={task.id} elevation={0} sx={{ p: 1.5, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
            <Stack direction="row" sx={{ alignItems: 'center', gap: 1 }}>
              <AppIcon icon={task.done ? 'verified' : 'tasks'} size={20} color={task.done ? 'var(--bal-success)' : 'var(--bal-text-secondary)'} />
              <Typography variant="body2" sx={{ color: task.done ? 'text.secondary' : undefined }}>
                {task.label}
              </Typography>
            </Stack>
          </Paper>
        ))}
      </SectionShell>
    );
  }

  return (
    <Stack sx={{ gap: 1 }}>
      {draft.map((task) => (
        <Paper key={task.id} elevation={0} sx={{ p: 1, border: '1px solid', borderColor: 'divider', borderRadius: 2 }}>
          <Stack direction="row" sx={{ alignItems: 'center', gap: 1 }}>
            <FormControlLabel
              control={<Checkbox checked={task.done} onChange={(e) => update(task.id, { done: e.target.checked })} />}
              label=""
              sx={{ m: 0 }}
              aria-label={t('task_done')}
            />
            <TextField label={t('task_label')} value={task.label} onChange={(e) => update(task.id, { label: e.target.value })} size="small" fullWidth required />
            <IconButton aria-label={t('remove')} onClick={() => remove(task.id)} size="small">
              <AppIcon icon="delete" size={20} color="var(--bal-error)" />
            </IconButton>
          </Stack>
        </Paper>
      ))}
      <EditActions onAdd={add} onCancel={() => setEditing(false)} onSave={() => onSave(draft, () => setEditing(false))} saving={saving} canSave={canSave} />
    </Stack>
  );
}

// ── History (سوابق) — patient-scoped, read-only, paged ────────────────────────────────────────────────────
function HistoryTab({ patientId }: { patientId: number }) {
  const t = useTranslations('records');
  const locale = useLocale();
  const [page, setPage] = useState(1);
  const history = usePatientHistory(patientId, page);

  if (history.isLoading) {
    return (
      <Stack sx={{ gap: 1.5 }}>
        <Skeleton variant="rounded" height={96} />
        <Skeleton variant="rounded" height={96} />
      </Stack>
    );
  }
  if (history.isError || !history.data) {
    return (
      <Typography variant="body2" sx={{ color: 'text.secondary' }}>
        {t('load_error')}
      </Typography>
    );
  }

  const { items, total, pageSize } = history.data;
  if (items.length === 0) {
    return (
      <Typography variant="body2" sx={{ color: 'text.secondary' }}>
        {t('history_empty')}
      </Typography>
    );
  }

  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  return (
    <Stack sx={{ gap: 1.5 }}>
      {items.map((note) => (
        <VisitNoteCard key={note.id} note={note} dateLabel={formatShamsiDate(note.recordedAt, locale)} authorFallback={t('author_fallback')} />
      ))}
      {totalPages > 1 ? (
        <Stack direction="row" sx={{ gap: 1, justifyContent: 'center', alignItems: 'center' }}>
          <AppButton variant="text" color="primary" disabled={page <= 1 || history.isFetching} onClick={() => setPage((n) => Math.max(1, n - 1))}>
            {t('prev')}
          </AppButton>
          <Typography variant="caption" sx={{ color: 'text.secondary' }}>
            {t('page_of', { page, total: totalPages })}
          </Typography>
          <AppButton variant="text" color="primary" disabled={page >= totalPages || history.isFetching} onClick={() => setPage((n) => n + 1)}>
            {t('next')}
          </AppButton>
        </Stack>
      ) : null}
    </Stack>
  );
}

// ── Small shared bits ─────────────────────────────────────────────────────────────────────────────────────
function SectionShell({
  canEdit,
  onEdit,
  empty,
  emptyLabel,
  children,
}: {
  canEdit: boolean;
  onEdit: () => void;
  empty: boolean;
  emptyLabel: string;
  children: React.ReactNode;
}) {
  const tc = useTranslations('records');
  return (
    <Stack sx={{ gap: 1.5 }}>
      {canEdit ? (
        <AppButton variant="text" color="primary" startIcon="edit" onClick={onEdit} sx={{ alignSelf: 'flex-end' }}>
          {tc('edit')}
        </AppButton>
      ) : null}
      {empty ? (
        <Typography variant="body2" sx={{ color: 'text.secondary' }}>
          {emptyLabel}
        </Typography>
      ) : (
        <Stack sx={{ gap: 1 }}>{children}</Stack>
      )}
    </Stack>
  );
}

function EditActions({
  onAdd,
  onCancel,
  onSave,
  saving,
  canSave,
}: {
  onAdd: () => void;
  onCancel: () => void;
  onSave: () => void;
  saving: boolean;
  canSave: boolean;
}) {
  const t = useTranslations('records');
  const tc = useTranslations('common');
  return (
    <Stack sx={{ gap: 1 }}>
      <AppButton variant="outlined" color="primary" startIcon="add" onClick={onAdd} sx={{ alignSelf: 'flex-start' }}>
        {t('add_item')}
      </AppButton>
      <Stack direction="row" sx={{ gap: 1, justifyContent: 'flex-end' }}>
        <AppButton variant="text" color="primary" onClick={onCancel} disabled={saving}>
          {tc('cancel')}
        </AppButton>
        <AppButton variant="contained" color="primary" onClick={onSave} disabled={saving || !canSave}>
          {saving ? tc('saving') : tc('save')}
        </AppButton>
      </Stack>
    </Stack>
  );
}

function BackToPatients() {
  const t = useTranslations('records');
  const router = useRouter();
  const locale = useLocale();
  return (
    <AppButton
      variant="outlined"
      color="primary"
      onClick={() => router.push(`/${locale}${ROUTES.PATIENTS}`)}
      sx={{ alignSelf: 'flex-start' }}
    >
      {t('back_to_patients')}
    </AppButton>
  );
}

function RecordSkeleton() {
  return (
    <Stack sx={{ gap: 3, maxWidth: 640, mx: 'auto', width: '100%' }}>
      <Stack sx={{ gap: 1 }}>
        <Skeleton variant="text" width="50%" height={32} />
        <Skeleton variant="text" width="30%" />
      </Stack>
      <Skeleton variant="rounded" height={56} />
      <Skeleton variant="rounded" height={48} />
      <Skeleton variant="rounded" height={96} />
    </Stack>
  );
}
