import React, { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { CheckIcon, XMarkIcon, TrashIcon, PlusIcon, PencilIcon, ClipboardDocumentIcon } from '@heroicons/react/24/outline';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse, PaginatedResponse } from '../lib/api';
import type { SmsTemplate, SmsLog, SmsMessageText } from '../types';
import { formatDate, formatDateTime } from '../lib/utils';
import DataTable, { Column } from '../components/ui/DataTable';
import StatusBadge from '../components/ui/StatusBadge';
import Pagination from '../components/ui/Pagination';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import Modal from '../components/ui/Modal';
import SearchableSelect from '../components/ui/SearchableSelect';

const templateSchema = z.object({
  name: z.string().min(2, 'نام قالب الزامی است'),
  body: z.string().min(5, 'متن قالب الزامی است'),
});
type TemplateFormData = z.infer<typeof templateSchema>;

type Tab = 'samples' | 'pending' | 'logs' | 'post-visit-approved' | 'messages';

const STATUS_LOG_META: Record<string, { label: string; cls: string }> = {
  sent: { label: 'ارسال شده', cls: 'green' },
  failed: { label: 'ناموفق', cls: 'red' },
  queued: { label: 'در صف', cls: 'amber' },
};

const TAG_LABELS: Record<string, string> = {
  global: 'سیستمی',
  otp: 'کد تأیید',
  payment: 'پرداخت',
  clinic_invitation: 'دعوت کلینیک',
  pre_registration: 'پیش‌ثبت‌نام',
  notification_mobile: 'تأیید موبایل',
  user_template: 'قالب کاربر',
};

const TAG_FILTER_OPTIONS = [
  { value: '', label: 'همه تگ‌ها' },
  ...Object.entries(TAG_LABELS).map(([value, label]) => ({ value, label })),
];

// الگوی تمپلت کاوه‌نگار را از body (با {var}) و token_map (var→slot) می‌سازد:
// هر {var} با %slot جایگزین می‌شود.
function buildKavenegarPattern(body: string, tokenMap: Record<string, string>): string {
  return body.replace(/\{([a-zA-Z0-9_]+)\}/g, (whole, key) =>
    tokenMap[key] ? `%${tokenMap[key]}` : whole,
  );
}

function KavenegarGuide({ msg }: { msg: SmsMessageText }) {
  const tokenMap = msg.token_map ?? {};
  const pattern = buildKavenegarPattern(msg.body, tokenMap);
  const templateName = msg.kavenegar_template ?? '';

  const copy = (text: string, label: string) => {
    navigator.clipboard.writeText(text).then(
      () => toast.success(`${label} کپی شد`),
      () => toast.error('کپی ناموفق بود'),
    );
  };

  return (
    <details style={{ marginTop: 4 }}>
      <summary style={{ cursor: 'pointer', fontSize: 12, color: 'var(--primary)', userSelect: 'none' }}>
        نحوه تعریف این تمپلت در پنل کاوه‌نگار
      </summary>
      <div style={{ marginTop: 8, padding: 12, background: 'var(--surface-2)', borderRadius: 'var(--r-sm)', display: 'flex', flexDirection: 'column', gap: 10 }}>
        <div style={{ fontSize: 11, color: 'var(--text-3)', lineHeight: 1.8 }}>
          در پنل کاوه‌نگار → بخش «الگوها» یک الگوی جدید با نام و متن زیر بسازید و تأیید بگیرید.
          متن واقعی پیامک از همین الگو ارسال می‌شود.
        </div>

        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontSize: 12, color: 'var(--text-2)', minWidth: 90 }}>نام الگو:</span>
          <code dir="ltr" style={{ fontSize: 12, flex: 1, direction: 'ltr' }}>{templateName || '—'}</code>
          <button type="button" className="btn ghost sm" disabled={!templateName} onClick={() => copy(templateName, 'نام الگو')}>
            <ClipboardDocumentIcon style={{ width: 13, height: 13 }} /> کپی
          </button>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <span style={{ fontSize: 12, color: 'var(--text-2)' }}>متن الگو (با %token):</span>
            <button type="button" className="btn ghost sm" onClick={() => copy(pattern, 'متن الگو')}>
              <ClipboardDocumentIcon style={{ width: 13, height: 13 }} /> کپی متن
            </button>
          </div>
          <pre dir="rtl" style={{ margin: 0, padding: 10, background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 'var(--r-sm)', fontSize: 13, lineHeight: 1.9, whiteSpace: 'pre-wrap', fontFamily: 'inherit' }}>
            {pattern}
          </pre>
        </div>

        {Object.keys(tokenMap).length > 0 && (
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
            <span style={{ fontSize: 11, color: 'var(--text-3)' }}>نگاشت متغیرها:</span>
            {Object.entries(tokenMap).map(([k, slot]) => (
              <span key={k} className="chip" dir="ltr">{`{${k}} → %${slot}`}</span>
            ))}
          </div>
        )}

        <div style={{ fontSize: 11, color: 'var(--text-3)', lineHeight: 1.8 }}>
          توجه: <code dir="ltr">token</code>، <code dir="ltr">token2</code>، <code dir="ltr">token3</code> فاصله نمی‌پذیرند؛
          مقادیر دارای فاصله در <code dir="ltr">token10</code>/<code dir="ltr">token20</code> قرار می‌گیرند.
        </div>
      </div>
    </details>
  );
}

export default function SmsPage() {
  const qc = useQueryClient();
  const [activeTab, setActiveTab] = useState<Tab>('samples');
  const [page, setPage] = useState(1);
  const [approveTarget, setApproveTarget] = useState<SmsTemplate | null>(null);
  const [rejectTarget, setRejectTarget] = useState<SmsTemplate | null>(null);
  const [rejectReason, setRejectReason] = useState('');
  const [addOpen, setAddOpen] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<SmsTemplate | null>(null);
  const [postVisitRejectId, setPostVisitRejectId] = useState<number | null>(null);
  const [postVisitRejectReason, setPostVisitRejectReason] = useState('');
  const [tagFilter, setTagFilter] = useState('');
  const [viewLog, setViewLog] = useState<SmsLog | null>(null);
  const [editMsg, setEditMsg] = useState<SmsMessageText | null>(null);
  const [editBody, setEditBody] = useState('');
  const [editKaveName, setEditKaveName] = useState('');
  const [editTemplate, setEditTemplate] = useState<SmsTemplate | null>(null);
  const [editTplName, setEditTplName] = useState('');
  const [editTplBody, setEditTplBody] = useState('');
  const limit = 15;

  const sampleTemplatesQuery = useQuery({
    queryKey: ['sms-samples', page],
    queryFn: () =>
      api.get<PaginatedResponse<SmsTemplate>>(
        `/api/v1/admin/sms/sample-templates?status=approved&page=${page}&limit=${limit}`,
      ),
    enabled: activeTab === 'samples',
  });

  const pendingTemplatesQuery = useQuery({
    queryKey: ['sms-pending', activeTab === 'pending' ? page : 1],
    queryFn: () =>
      api.get<PaginatedResponse<SmsTemplate>>(
        `/api/v1/admin/sms/sample-templates?status=pending&page=${activeTab === 'pending' ? page : 1}&limit=${limit}`,
      ),
  });

  const logsQuery = useQuery({
    queryKey: ['sms-logs', page, tagFilter],
    queryFn: () =>
      api.get<PaginatedResponse<SmsLog>>(
        `/api/v1/admin/sms/logs?page=${page}&limit=${limit}` + (tagFilter ? `&tag=${tagFilter}` : ''),
      ),
    enabled: activeTab === 'logs',
  });

  const messagesQuery = useQuery({
    queryKey: ['sms-messages'],
    queryFn: () => api.get<ApiResponse<{ data: SmsMessageText[] }>>('/api/v1/admin/sms/messages'),
    enabled: activeTab === 'messages',
  });

  const updateMessageMut = useMutation({
    mutationFn: ({ tag, body, kavenegarTemplate }: { tag: string; body: string; kavenegarTemplate: string }) =>
      api.patch<ApiResponse<SmsMessageText>>(`/api/v1/admin/sms/messages/${tag}`, { body, kavenegar_template: kavenegarTemplate }),
    onSuccess: () => {
      toast.success('متن پیامک به‌روزرسانی شد');
      setEditMsg(null);
      qc.invalidateQueries({ queryKey: ['sms-messages'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const { register, handleSubmit, reset, formState: { errors, isSubmitting } } = useForm<TemplateFormData>({
    resolver: zodResolver(templateSchema),
  });

  const createMutation = useMutation({
    mutationFn: (d: TemplateFormData) =>
      api.post<ApiResponse<SmsTemplate>>('/api/v1/sms/template', d),
    onSuccess: () => {
      toast.success('قالب اضافه شد');
      setAddOpen(false);
      reset();
      qc.invalidateQueries({ queryKey: ['sms-samples'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const updateTemplateMut = useMutation({
    mutationFn: ({ uuid, name, body }: { uuid: string; name: string; body: string }) =>
      api.patch<ApiResponse<SmsTemplate>>(`/api/v1/sms/template/${uuid}`, { name, body }),
    onSuccess: () => {
      toast.success('قالب ویرایش شد');
      setEditTemplate(null);
      qc.invalidateQueries({ queryKey: ['sms-samples'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const approveMutation = useMutation({
    mutationFn: (t: SmsTemplate) =>
      api.post<ApiResponse<null>>(`/api/v1/admin/sms/template/${t.uuid}/approve`, {}),
    onSuccess: () => {
      toast.success('قالب تأیید شد');
      setApproveTarget(null);
      qc.invalidateQueries({ queryKey: ['sms-pending'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const rejectMutation = useMutation({
    mutationFn: ({ t, reason }: { t: SmsTemplate; reason: string }) =>
      api.post<ApiResponse<null>>(`/api/v1/admin/sms/template/${t.uuid}/reject`, { reason }),
    onSuccess: () => {
      toast.success('قالب رد شد');
      setRejectTarget(null);
      setRejectReason('');
      qc.invalidateQueries({ queryKey: ['sms-pending'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const deleteMutation = useMutation({
    mutationFn: (t: SmsTemplate) =>
      api.delete<ApiResponse<null>>(`/api/v1/sms/template/${t.uuid}`),
    onSuccess: () => {
      toast.success('قالب حذف شد');
      setDeleteTarget(null);
      qc.invalidateQueries({ queryKey: ['sms-samples'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  type PostVisitItem = { id: number; entity_type: string; entity_id: number; entity_name?: string | null; post_visit_text_pending: string; post_visit_text: string | null; post_visit_text_status: string };

  const postVisitReviewQuery = useQuery<ApiResponse<{ data: PostVisitItem[] }>>({
    queryKey: ['sms-post-visit-review'],
    queryFn: () => api.get('/api/v1/admin/sms/settings/review?status=pending'),
    enabled: activeTab === 'pending',
  });

  const postVisitApprovedQuery = useQuery<ApiResponse<{ data: PostVisitItem[] }>>({
    queryKey: ['sms-post-visit-approved'],
    queryFn: () => api.get('/api/v1/admin/sms/settings/review?status=approved'),
    enabled: activeTab === 'post-visit-approved',
  });

  const postVisitApproveMutation = useMutation({
    mutationFn: (id: number) => api.post(`/api/v1/admin/sms/settings/${id}/approve`, {}),
    onSuccess: () => {
      toast.success('متن پیامک تأیید شد');
      qc.invalidateQueries({ queryKey: ['sms-post-visit-review'] });
      qc.invalidateQueries({ queryKey: ['sms-post-visit-approved'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const postVisitRejectMutation = useMutation({
    mutationFn: ({ id, reason }: { id: number; reason: string }) =>
      api.post(`/api/v1/admin/sms/settings/${id}/reject`, { reason }),
    onSuccess: () => {
      toast.success('متن پیامک رد شد');
      setPostVisitRejectId(null);
      setPostVisitRejectReason('');
      qc.invalidateQueries({ queryKey: ['sms-post-visit-review'] });
    },
    onError: (err: Error) => toast.error(err.message),
  });

  const templateColumns: Column<SmsTemplate>[] = [
    { key: 'name', header: 'نام', render: (t) => <b>{t.name}</b> },
    {
      key: 'body',
      header: 'محتوا',
      render: (t) => <span className="muted" style={{ fontSize: 12, display: 'block', maxWidth: 280, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{t.body}</span>,
    },
    { key: 'status', header: 'وضعیت', render: (t) => <StatusBadge type="sms" value={t.status} /> },
    { key: 'created_at', header: 'تاریخ', render: (t) => formatDate(t.created_at) },
  ];

  const pendingColumns: Column<SmsTemplate>[] = templateColumns.filter((c) => c.key !== 'status');

  const logColumns: Column<SmsLog>[] = [
    { key: 'recipient', header: 'گیرنده', render: (l) => <span dir="ltr">{l.recipient}</span> },
    {
      key: 'message',
      header: 'پیام',
      render: (l) => (
        <button
          type="button"
          title="نمایش متن کامل"
          onClick={() => setViewLog(l)}
          className="muted"
          style={{ fontSize: 12, display: 'block', maxWidth: 280, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', textAlign: 'right', background: 'none', border: 'none', padding: 0, cursor: 'pointer', color: 'var(--primary)', width: '100%' }}
        >
          {l.message}
        </button>
      ),
    },
    {
      key: 'status',
      header: 'وضعیت',
      render: (l) => {
        const meta = STATUS_LOG_META[l.status] ?? { label: l.status, cls: 'gray' };
        return <span className={`badge ${meta.cls}`}><span className="bdot" />{meta.label}</span>;
      },
    },
    { key: 'tag', header: 'تگ', render: (l) => <span className="badge gray"><span className="bdot" />{TAG_LABELS[l.tag] ?? l.tag}</span> },
    { key: 'template', header: 'الگوی کاوه‌نگار', render: (l) => l.template ? <code dir="ltr" style={{ fontSize: 12 }}>{l.template}</code> : <span className="muted">—</span> },
    { key: 'provider', header: 'سرویس‌دهنده' },
    { key: 'sent_at', header: 'زمان ارسال', render: (l) => formatDateTime(l.sent_at) },
  ];

  const pendingCount = pendingTemplatesQuery.data?.meta?.totalRecords ?? 0;

  const handleTabChange = (tab: Tab) => {
    setActiveTab(tab);
    setPage(1);
  };

  const postVisitPending = (postVisitReviewQuery.data?.data as any)?.data ?? [];
  const postVisitApproved = (postVisitApprovedQuery.data?.data as any)?.data ?? [];
  const pendingBadge = pendingCount + postVisitPending.length;

  const TABS: { key: Tab; label: string; badge?: number }[] = [
    { key: 'samples', label: 'قالب‌های نمونه' },
    { key: 'pending', label: 'در انتظار تأیید', badge: pendingBadge },
    { key: 'post-visit-approved', label: 'پیامک‌های تأیید شده' },
    { key: 'logs', label: 'لاگ‌های ارسال' },
    { key: 'messages', label: 'متن پیامک‌ها' },
  ];

  return (
    <div className="fade-in">
      <div className="card-title-row" style={{ marginBottom: 'var(--gap)' }}>
        <div>
          <h1 className="section-title">پیامک</h1>
          <div className="muted">مدیریت قالب‌های پیامک</div>
        </div>
        {activeTab === 'samples' && (
          <button onClick={() => setAddOpen(true)} className="btn primary sm">
            <PlusIcon style={{ width: 16, height: 16 }} />
            افزودن قالب
          </button>
        )}
      </div>

      <div className="card">
        {/* Tabs */}
        <div style={{ display: 'flex', borderBottom: '1px solid var(--border)', padding: '0 var(--card-pad)' }}>
          {TABS.map((t) => (
            <button
              key={t.key}
              onClick={() => handleTabChange(t.key)}
              style={{
                padding: '14px 16px',
                fontSize: 14,
                fontWeight: 500,
                border: 'none',
                background: 'none',
                cursor: 'pointer',
                borderBottom: `2px solid ${activeTab === t.key ? 'var(--primary)' : 'transparent'}`,
                color: activeTab === t.key ? 'var(--primary)' : 'var(--text-2)',
                display: 'flex',
                alignItems: 'center',
                gap: 6,
                marginBottom: -1,
                transition: 'color .15s',
              }}
            >
              {t.label}
              {t.badge != null && t.badge > 0 && (
                <span style={{
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  minWidth: 18, height: 18, padding: '0 4px', borderRadius: 9,
                  fontSize: 10, fontWeight: 700,
                  background: 'oklch(0.62 0.22 30)', color: '#fff', lineHeight: 1,
                }}>
                  {t.badge}
                </span>
              )}
            </button>
          ))}
        </div>

        <div className="card-pad" style={{ paddingTop: 'var(--card-pad)' }}>
          {activeTab === 'samples' && (
            <>
              <DataTable<SmsTemplate>
                columns={templateColumns}
                data={sampleTemplatesQuery.data?.data ?? []}
                loading={sampleTemplatesQuery.isLoading}
                emptyMessage="هیچ قالبی یافت نشد"
                actions={(t) => (
                  <>
                    <button
                      onClick={() => { setEditTemplate(t); setEditTplName(t.name); setEditTplBody(t.body); }}
                      className="mini-btn" title="ویرایش"
                    >
                      <PencilIcon style={{ width: 15, height: 15 }} />
                    </button>
                    <button onClick={() => setDeleteTarget(t)} className="mini-btn danger" title="حذف">
                      <TrashIcon style={{ width: 15, height: 15 }} />
                    </button>
                  </>
                )}
              />
              <Pagination
                page={page}
                total={sampleTemplatesQuery.data?.meta?.totalRecords ?? 0}
                limit={limit}
                onPageChange={setPage}
              />
            </>
          )}

          {activeTab === 'pending' && (
            <>
              {pendingCount > 0 && (
                <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--text-2)', marginBottom: 8 }}>قالب‌های نمونه</div>
              )}
              <DataTable<SmsTemplate>
                columns={pendingColumns}
                data={pendingTemplatesQuery.data?.data ?? []}
                loading={pendingTemplatesQuery.isLoading}
                emptyMessage="قالب نمونه‌ای در انتظار تأیید نیست"
                actions={(t) => (
                  <>
                    <button onClick={() => setApproveTarget(t)} className="mini-btn" title="تأیید">
                      <CheckIcon style={{ width: 15, height: 15 }} />
                    </button>
                    <button onClick={() => setRejectTarget(t)} className="mini-btn danger" title="رد">
                      <XMarkIcon style={{ width: 15, height: 15 }} />
                    </button>
                  </>
                )}
              />
              <Pagination
                page={page}
                total={pendingTemplatesQuery.data?.meta?.totalRecords ?? 0}
                limit={limit}
                onPageChange={setPage}
              />

              <div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--text-2)', margin: '20px 0 8px' }}>متن پیامک ویزیت</div>
              {postVisitReviewQuery.isLoading ? (
                <div className="muted" style={{ fontSize: 13 }}>در حال بارگذاری...</div>
              ) : postVisitPending.length === 0 ? (
                <div style={{ textAlign: 'center', padding: '24px 16px', color: 'var(--text-3)', fontSize: 13 }}>
                  متن ویزیتی در انتظار تأیید نیست
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
                  {postVisitPending.map((item: PostVisitItem) => (
                    <div key={item.id} className="card card-pad">
                      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 10 }}>
                        <div>
                          <span className="badge gray" style={{ fontSize: 11 }}>
                            {item.entity_type === 'doctor' ? 'پزشک' : item.entity_type === 'clinic' ? 'کلینیک' : item.entity_type}
                            {item.entity_name ? `: ${item.entity_name}` : ` #${item.entity_id}`}
                          </span>
                        </div>
                        <div style={{ display: 'flex', gap: 8 }}>
                          <button
                            className="btn primary sm"
                            disabled={postVisitApproveMutation.isPending}
                            onClick={() => postVisitApproveMutation.mutate(item.id)}
                          >
                            <CheckIcon style={{ width: 14 }} /> تأیید
                          </button>
                          <button
                            className="btn danger sm"
                            onClick={() => { setPostVisitRejectId(item.id); setPostVisitRejectReason(''); }}
                          >
                            <XMarkIcon style={{ width: 14 }} /> رد
                          </button>
                        </div>
                      </div>
                      <div style={{ fontSize: 13, lineHeight: 1.8, padding: '10px 14px', background: 'var(--surface)', borderRadius: 8, border: '1px solid var(--border)', direction: 'rtl' }}>
                        {item.post_visit_text_pending}
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </>
          )}

          {activeTab === 'post-visit-approved' && (
            <>
              {postVisitApprovedQuery.isLoading ? (
                <div className="muted" style={{ fontSize: 13 }}>در حال بارگذاری...</div>
              ) : postVisitApproved.length === 0 ? (
                <div style={{ textAlign: 'center', padding: '24px 16px', color: 'var(--text-3)', fontSize: 13 }}>
                  متن تأییدشده‌ای وجود ندارد
                </div>
              ) : (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
                  {postVisitApproved.map((item: PostVisitItem) => (
                    <div key={item.id} className="card card-pad">
                      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 10 }}>
                        <span className="badge gray" style={{ fontSize: 11 }}>
                          {item.entity_type === 'doctor' ? 'پزشک' : item.entity_type === 'clinic' ? 'کلینیک' : item.entity_type}
                          {item.entity_name ? `: ${item.entity_name}` : ` #${item.entity_id}`}
                        </span>
                        <span className="badge green" style={{ fontSize: 11 }}><span className="bdot" />تأیید شده</span>
                      </div>
                      <div style={{ fontSize: 13, lineHeight: 1.8, padding: '10px 14px', background: 'var(--surface)', borderRadius: 8, border: '1px solid var(--border)', direction: 'rtl' }}>
                        {item.post_visit_text}
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </>
          )}

          {activeTab === 'logs' && (
            <>
              <div style={{ marginBottom: 12, display: 'flex', justifyContent: 'flex-end' }}>
                <div style={{ width: 200 }}>
                  <SearchableSelect
                    options={TAG_FILTER_OPTIONS.map((o) => ({ value: o.value, label: o.label }))}
                    value={tagFilter}
                    onChange={(v) => { setTagFilter(v ? String(v) : ''); setPage(1); }}
                    placeholder="همه تگ‌ها"
                  />
                </div>
              </div>
              <DataTable<SmsLog>
                columns={logColumns}
                data={logsQuery.data?.data ?? []}
                loading={logsQuery.isLoading}
                emptyMessage="لاگی یافت نشد"
              />
              <Pagination
                page={page}
                total={logsQuery.data?.meta?.totalRecords ?? 0}
                limit={limit}
                onPageChange={setPage}
              />
            </>
          )}

          {activeTab === 'messages' && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              {(((messagesQuery.data?.data as any)?.data ?? []) as SmsMessageText[]).map((m) => (
                <div key={m.tag} className="card card-pad" style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <b style={{ fontSize: 14 }}>{m.title}</b>
                    <button className="btn ghost sm" onClick={() => { setEditMsg(m); setEditBody(m.body); setEditKaveName(m.kavenegar_template ?? ''); }}>
                      <PencilIcon style={{ width: 14, height: 14 }} /> ویرایش
                    </button>
                  </div>
                  <div className="muted" style={{ fontSize: 13, lineHeight: 1.9, whiteSpace: 'pre-wrap', direction: 'rtl' }}>{m.body}</div>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                    <span className="muted" style={{ fontSize: 12 }}>تمپلت کاوه‌نگار:</span>
                    <span className={`badge ${m.kavenegar_template ? 'green' : 'gray'}`} dir="ltr" style={{ fontSize: 11 }}>
                      {m.kavenegar_template || 'تعریف‌نشده'}
                    </span>
                  </div>
                  <KavenegarGuide msg={m} />
                  {m.variables.length > 0 && (
                    <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                      {m.variables.map((v) => <span key={v} className="chip" dir="ltr">{`{${v}}`}</span>)}
                    </div>
                  )}
                </div>
              ))}
              {messagesQuery.isLoading && <p className="muted">در حال بارگذاری...</p>}
            </div>
          )}
        </div>
      </div>

      <Modal
        open={editMsg !== null}
        title={`ویرایش متن: ${editMsg?.title ?? ''}`}
        onClose={() => setEditMsg(null)}
        footer={
          <>
            <button className="btn ghost sm" onClick={() => setEditMsg(null)}>انصراف</button>
            <button
              className="btn primary sm"
              disabled={updateMessageMut.isPending || !editBody.trim()}
              onClick={() => editMsg && updateMessageMut.mutate({ tag: editMsg.tag, body: editBody, kavenegarTemplate: editKaveName })}
            >
              {updateMessageMut.isPending ? 'در حال ذخیره...' : 'ذخیره'}
            </button>
          </>
        }
      >
        <div className="form-row">
          <label>متن پیامک (پیش‌نمایش/لاگ)</label>
          <textarea className="input" rows={5} dir="rtl" value={editBody} onChange={(e) => setEditBody(e.target.value)} />
        </div>
        <div className="form-row">
          <label>نام تمپلت کاوه‌نگار (VerifyLookup)</label>
          <input className="input" dir="ltr" value={editKaveName} onChange={(e) => setEditKaveName(e.target.value)} placeholder="clinicpro-otp" />
          <span className="muted" style={{ fontSize: 11, marginTop: 4 }}>
            این نام باید دقیقاً با تمپلت تأییدشده در پنل کاوه‌نگار یکی باشد. متن واقعی پیامک از پنل کاوه‌نگار ارسال می‌شود، نه از این متن.
          </span>
        </div>
        {editMsg && editMsg.variables.length > 0 && (
          <div style={{ marginTop: 10, display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
            <span className="muted" style={{ fontSize: 12 }}>متغیرها → token:</span>
            {editMsg.variables.map((v) => (
              <span key={v} className="chip" dir="ltr">{`{${v}}`}{editMsg.token_map?.[v] ? ` → %${editMsg.token_map[v]}` : ''}</span>
            ))}
          </div>
        )}
      </Modal>

      <Modal open={addOpen} title="افزودن قالب نمونه" onClose={() => setAddOpen(false)}
        footer={
          <>
            <button onClick={() => setAddOpen(false)} className="btn ghost sm">لغو</button>
            <button form="add-sms-form" type="submit" disabled={isSubmitting} className="btn primary sm">
              {isSubmitting ? 'در حال ذخیره...' : 'ذخیره'}
            </button>
          </>
        }
      >
        <form id="add-sms-form" onSubmit={handleSubmit((d) => createMutation.mutate(d))}>
          <div className="form-row">
            <label>نام قالب</label>
            <input {...register('name')} placeholder="مثال: تأیید نوبت" className="input" />
            {errors.name && <p className="err-text">{errors.name.message}</p>}
          </div>
          <div className="form-row" style={{ marginTop: 12 }}>
            <label>متن قالب</label>
            <textarea {...register('body')} rows={4} placeholder="متن پیامک..."
              className="input" style={{ resize: 'none', height: 'auto' }} />
            {errors.body && <p className="err-text">{errors.body.message}</p>}
          </div>
        </form>
      </Modal>

      <Modal
        open={editTemplate !== null}
        title="ویرایش قالب نمونه"
        onClose={() => setEditTemplate(null)}
        footer={
          <>
            <button onClick={() => setEditTemplate(null)} className="btn ghost sm">لغو</button>
            <button
              className="btn primary sm"
              disabled={updateTemplateMut.isPending || !editTplName.trim() || !editTplBody.trim()}
              onClick={() => editTemplate && updateTemplateMut.mutate({ uuid: editTemplate.uuid, name: editTplName, body: editTplBody })}
            >
              {updateTemplateMut.isPending ? 'در حال ذخیره...' : 'ذخیره'}
            </button>
          </>
        }
      >
        <div className="form-row">
          <label>نام قالب</label>
          <input className="input" value={editTplName} onChange={(e) => setEditTplName(e.target.value)} />
        </div>
        <div className="form-row" style={{ marginTop: 12 }}>
          <label>متن قالب</label>
          <textarea className="input" rows={4} dir="rtl" value={editTplBody}
            onChange={(e) => setEditTplBody(e.target.value)} style={{ resize: 'none', height: 'auto' }} />
        </div>
        {editTemplate?.status === 'approved' && (
          <p className="muted" style={{ fontSize: 12, marginTop: 8 }}>
            توجه: با ویرایش، این قالبِ تأییدشده به «پیش‌نویس» برمی‌گردد و باید دوباره برای تأیید ارسال شود.
          </p>
        )}
      </Modal>

      <Modal open={!!rejectTarget} title="رد قالب پیامک"
        onClose={() => { setRejectTarget(null); setRejectReason(''); }}
        footer={
          <>
            <button onClick={() => { setRejectTarget(null); setRejectReason(''); }} className="btn ghost sm">لغو</button>
            <button
              onClick={() => rejectTarget && rejectMutation.mutate({ t: rejectTarget, reason: rejectReason })}
              disabled={!rejectReason || rejectMutation.isPending}
              className="btn danger sm">
              رد کردن
            </button>
          </>
        }
      >
        <div className="form-row">
          <label>دلیل رد</label>
          <textarea value={rejectReason} onChange={(e) => setRejectReason(e.target.value)}
            rows={4} placeholder="دلیل رد را بنویسید..."
            className="input" style={{ resize: 'none', height: 'auto' }} />
        </div>
      </Modal>

      <Modal open={!!postVisitRejectId} title="رد متن پیامک ویزیت"
        onClose={() => { setPostVisitRejectId(null); setPostVisitRejectReason(''); }}
        footer={
          <>
            <button onClick={() => { setPostVisitRejectId(null); setPostVisitRejectReason(''); }} className="btn ghost sm">لغو</button>
            <button
              onClick={() => postVisitRejectId && postVisitRejectMutation.mutate({ id: postVisitRejectId, reason: postVisitRejectReason })}
              disabled={!postVisitRejectReason || postVisitRejectMutation.isPending}
              className="btn danger sm">
              رد کردن
            </button>
          </>
        }
      >
        <div className="form-row">
          <label>دلیل رد</label>
          <textarea value={postVisitRejectReason} onChange={(e) => setPostVisitRejectReason(e.target.value)}
            rows={4} placeholder="دلیل رد را بنویسید..."
            className="input" style={{ resize: 'none', height: 'auto' }} />
        </div>
      </Modal>

      <ConfirmDialog
        open={!!approveTarget}
        title="تأیید قالب پیامک"
        message={`قالب "${approveTarget?.name}" را تأیید می‌کنید؟`}
        confirmLabel="تأیید"
        loading={approveMutation.isPending}
        onConfirm={() => approveTarget && approveMutation.mutate(approveTarget)}
        onCancel={() => setApproveTarget(null)}
      />

      <ConfirmDialog
        open={!!deleteTarget}
        title="حذف قالب"
        message={`آیا از حذف قالب "${deleteTarget?.name}" اطمینان دارید؟`}
        confirmLabel="حذف"
        danger
        loading={deleteMutation.isPending}
        onConfirm={() => deleteTarget && deleteMutation.mutate(deleteTarget)}
        onCancel={() => setDeleteTarget(null)}
      />

      <Modal open={!!viewLog} title="متن کامل پیامک" onClose={() => setViewLog(null)}>
        {viewLog && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12, minWidth: 320 }}>
            <div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', fontSize: 12.5 }}>
              <div><span className="muted">گیرنده: </span><span dir="ltr">{viewLog.recipient}</span></div>
              <div><span className="muted">تگ: </span>{TAG_LABELS[viewLog.tag] ?? viewLog.tag}</div>
              <div><span className="muted">زمان: </span>{formatDateTime(viewLog.sent_at)}</div>
            </div>
            <div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word', lineHeight: 1.9, fontSize: 14, padding: '12px 14px', borderRadius: 'var(--r-sm)', background: 'var(--surface-3)', border: '1px solid var(--border)' }}>
              {viewLog.message}
            </div>
            <div className="muted" style={{ fontSize: 11, textAlign: 'left' }}>
              {viewLog.message.length} کاراکتر
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}
