import { useEffect, useMemo, useRef, useState, type CSSProperties, type ReactNode } from 'react';
import { useForm, router } from '@inertiajs/react';
import { AppLayout } from '@/Components/Layout/AppLayout';
import { JalaliDatePicker } from '@/Components/Forms/JalaliDatePicker';

type NewsLayout = {
  badge?: string;
  align?: 'right' | 'center';
  density?: 'normal' | 'compact';
  linkText?: string;
  linkUrl?: string;
};

type NewsItem = {
  id: number;
  title: string;
  body: string;
  imagePath: string | null;
  isImportant: boolean;
  template: string;
  accentColor: string;
  layout: NewsLayout | null;
  audienceType: string;
  audienceValue: string | null;
  expiresAt: string | null;
  createdAt: string;
  sender: string;
  readCount: number;
};

type Classroom = { id: number; name: string };
type User = { id: number; name: string; role: string };

type Props = {
  news: NewsItem[];
  classrooms: Classroom[];
  users: User[];
  allowedRoles: string[];
  canTargetAll: boolean;
};

const roleLabels: Record<string, string> = {
  student: 'دانش‌آموزان',
  teacher: 'معلمان',
  principal: 'مدیر مدرسه',
  owner: 'مالک مدرسه',
  moaven: 'معاون',
};

const templates: Record<string, { label: string; helper: string; color: string; icon: string; bg: string }> = {
  info: { label: 'اطلاعیه', helper: 'آبی، مناسب خبرهای عادی', color: '#2563eb', icon: 'bi-info-circle-fill', bg: '#eff6ff' },
  warning: { label: 'هشدار', helper: 'زرد، برای یادآوری مهم', color: '#d97706', icon: 'bi-exclamation-triangle-fill', bg: '#fffbeb' },
  danger: { label: 'فوری', helper: 'قرمز، برای موارد حساس', color: '#dc2626', icon: 'bi-x-octagon-fill', bg: '#fef2f2' },
  success: { label: 'خبر خوب', helper: 'سبز، برای اعلام مثبت', color: '#16a34a', icon: 'bi-check-circle-fill', bg: '#f0fdf4' },
  custom: { label: 'سفارشی', helper: 'رنگ دلخواه شما', color: '#0EA678', icon: 'bi-palette-fill', bg: '#f8fafc' },
};

const emptyLayout: Required<NewsLayout> = {
  badge: '',
  align: 'right',
  density: 'normal',
  linkText: '',
  linkUrl: '',
};

function parseLayout(value: string | NewsLayout | null | undefined): Required<NewsLayout> {
  if (!value) return emptyLayout;
  if (typeof value === 'object') return { ...emptyLayout, ...value };
  try {
    return { ...emptyLayout, ...JSON.parse(value) };
  } catch {
    return emptyLayout;
  }
}

function audienceLabel(type: string, value: string | null, classrooms: Classroom[], users: User[]): string {
  if (type === 'all') return 'همه کاربران مدرسه';
  if (type === 'role') return roleLabels[value ?? ''] ?? 'نقش انتخاب نشده';
  if (type === 'classroom') return classrooms.find((c) => String(c.id) === String(value))?.name ?? 'کلاس انتخاب نشده';
  if (type === 'user') {
    const user = users.find((u) => String(u.id) === String(value));
    return user ? `${user.name} (${roleLabels[user.role] ?? user.role})` : 'کاربر انتخاب نشده';
  }
  return 'نامشخص';
}

export default function DashboardNews({ news, classrooms, users, allowedRoles, canTargetAll }: Props) {
  const [showForm, setShowForm] = useState(false);
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const bodyRef = useRef<HTMLTextAreaElement>(null);
  const firstRole = allowedRoles[0] ?? '';

  const { data, setData, post, processing, errors, reset } = useForm({
    title: '',
    body: '',
    image: null as File | null,
    is_important: false as boolean,
    template: 'info',
    accent_color: templates.info.color,
    layout_json: JSON.stringify(emptyLayout),
    audience_type: firstRole ? 'role' : (classrooms.length > 0 ? 'classroom' : 'user'),
    audience_value: firstRole,
    expires_at: '',
  });

  const layout = useMemo(() => parseLayout(data.layout_json), [data.layout_json]);

  useEffect(() => {
    if (!data.image) {
      setImagePreview(null);
      return;
    }
    const url = URL.createObjectURL(data.image);
    setImagePreview(url);
    return () => URL.revokeObjectURL(url);
  }, [data.image]);

  const setLayout = <K extends keyof Required<NewsLayout>>(key: K, value: Required<NewsLayout>[K]) => {
    setData('layout_json', JSON.stringify({ ...layout, [key]: value }));
  };

  const submit = (e: React.FormEvent) => {
    e.preventDefault();
    post('/school/news', {
      forceFormData: true,
      onSuccess: () => {
        reset();
        setShowForm(false);
      },
    });
  };

  const destroy = (id: number) => {
    if (!confirm('این خبر حذف شود؟')) return;
    router.delete(`/school/news/${id}`);
  };

  const appendBodyToken = (token: string) => {
    const current = data.body;
    const textarea = bodyRef.current;
    const start = textarea?.selectionStart ?? current.length;
    const end = textarea?.selectionEnd ?? current.length;
    const next = `${current.slice(0, start)}${token}${current.slice(end)}`;
    setData('body', next);
    requestAnimationFrame(() => textarea?.focus());
  };

  const selectedTemplate = templates[data.template] ?? templates.info;

  return (
    <AppLayout title="اخبار داشبورد">
      <div className="page-stack dashboard-news-page">
        <section className="section-header">
          <div>
            <h2>اخبار داشبورد</h2>
            <p>ساخت کارت‌های خبری برای داشبورد کاربران مدرسه با مخاطب دقیق، رنگ، تصویر و زمان انقضا.</p>
          </div>
          <button className="btn btn-primary" type="button" onClick={() => setShowForm((value) => !value)}>
            <i className="bi bi-plus-lg" /> خبر جدید
          </button>
        </section>

        {showForm && (
          <section className="news-composer">
            <form className="news-composer-form" onSubmit={submit}>
              <div className="news-composer-head">
                <div>
                  <span className="news-kicker">طراحی خبر</span>
                  <h3>کارت جدید داشبورد</h3>
                </div>
                <span className="news-template-chip" style={{ color: data.accent_color }}>
                  <i className={`bi ${selectedTemplate.icon}`} />
                  {selectedTemplate.label}
                </span>
              </div>

              <div className="news-form-grid">
                <div className="form-group">
                  <label className="form-label">عنوان خبر</label>
                  <input className="form-input" value={data.title} onChange={(event) => setData('title', event.target.value)} placeholder="مثلا: برنامه امتحان هفتگی" required />
                  {errors.title && <p className="form-error">{errors.title}</p>}
                </div>
                <div className="form-group">
                  <label className="form-label">برچسب روی کارت</label>
                  <input className="form-input" value={layout.badge} onChange={(event) => setLayout('badge', event.target.value)} placeholder="مثلا: فوری، اطلاعیه، یادآوری" />
                </div>
              </div>

              <div className="form-group">
                <div className="news-label-row">
                  <label className="form-label">متن خبر</label>
                  <div className="news-editor-tools">
                    <button type="button" onClick={() => appendBodyToken('**متن برجسته**')} title="متن برجسته">
                      <i className="bi bi-type-bold" />
                    </button>
                    <button type="button" onClick={() => appendBodyToken('[متن لینک](https://example.com)')} title="لینک">
                      <i className="bi bi-link-45deg" />
                    </button>
                  </div>
                </div>
                <textarea
                  ref={bodyRef}
                  className="form-input"
                  rows={5}
                  value={data.body}
                  onChange={(event) => setData('body', event.target.value)}
                  placeholder="متن خبر را بنویسید. برای برجسته‌سازی از دکمه B و برای لینک از دکمه لینک استفاده کنید."
                  required
                />
                {errors.body && <p className="form-error">{errors.body}</p>}
              </div>

              <div className="news-template-grid">
                {Object.entries(templates).map(([key, template]) => (
                  <button
                    key={key}
                    type="button"
                    className={`news-template-card${data.template === key ? ' is-selected' : ''}`}
                    onClick={() => {
                      setData('template', key);
                      if (key !== 'custom') setData('accent_color', template.color);
                    }}
                    style={{ '--template-color': template.color } as CSSProperties}
                  >
                    <i className={`bi ${template.icon}`} />
                    <span>{template.label}</span>
                    <small>{template.helper}</small>
                  </button>
                ))}
              </div>

              <div className="news-form-grid news-form-grid--three">
                <div className="form-group">
                  <label className="form-label">رنگ کارت</label>
                  <div className="news-color-field">
                    <input type="color" value={data.accent_color} onChange={(event) => setData('accent_color', event.target.value)} />
                    <span>{data.accent_color}</span>
                  </div>
                </div>
                <div className="form-group">
                  <label className="form-label">چینش متن</label>
                  <div className="segmented-control">
                    <button type="button" className={layout.align === 'right' ? 'is-active' : ''} onClick={() => setLayout('align', 'right')}>راست‌چین</button>
                    <button type="button" className={layout.align === 'center' ? 'is-active' : ''} onClick={() => setLayout('align', 'center')}>وسط‌چین</button>
                  </div>
                </div>
                <div className="form-group">
                  <label className="form-label">حالت کارت</label>
                  <div className="segmented-control">
                    <button type="button" className={layout.density === 'normal' ? 'is-active' : ''} onClick={() => setLayout('density', 'normal')}>کامل</button>
                    <button type="button" className={layout.density === 'compact' ? 'is-active' : ''} onClick={() => setLayout('density', 'compact')}>فشرده</button>
                  </div>
                </div>
              </div>

              <div className="news-form-grid">
                <div className="form-group">
                  <label className="form-label">متن دکمه لینک</label>
                  <input className="form-input" value={layout.linkText} onChange={(event) => setLayout('linkText', event.target.value)} placeholder="مثلا: مشاهده جزئیات" />
                </div>
                <div className="form-group">
                  <label className="form-label">آدرس لینک</label>
                  <input className="form-input" value={layout.linkUrl} onChange={(event) => setLayout('linkUrl', event.target.value)} placeholder="https://..." dir="ltr" />
                </div>
              </div>

              <div className="news-form-grid">
                <div className="form-group">
                  <label className="form-label">تصویر خبر</label>
                  <label className="news-upload">
                    <i className="bi bi-image" />
                    <span>{data.image ? data.image.name : 'انتخاب تصویر برای کارت'}</span>
                    <input type="file" accept="image/*" onChange={(event) => setData('image', event.target.files?.[0] ?? null)} />
                  </label>
                  {errors.image && <p className="form-error">{errors.image}</p>}
                </div>

                <JalaliDatePicker label="تاریخ انقضا" value={data.expires_at} onChange={(value) => setData('expires_at', value)} placeholder="بدون انقضا" />
              </div>

              <div className="news-form-grid">
                <div className="form-group">
                  <label className="form-label">مخاطب خبر</label>
                  <select
                    className="form-input"
                    value={data.audience_type}
                    onChange={(event) => {
                      const type = event.target.value;
                      setData('audience_type', type);
                      setData('audience_value', type === 'role' ? firstRole : '');
                    }}
                  >
                    {allowedRoles.length > 0 && <option value="role">بر اساس نقش</option>}
                    {classrooms.length > 0 && <option value="classroom">یک کلاس مشخص</option>}
                    {users.length > 0 && <option value="user">یک نفر مشخص</option>}
                    {canTargetAll && <option value="all">همه کاربران مدرسه</option>}
                  </select>
                </div>

                {data.audience_type === 'role' && (
                  <div className="form-group">
                    <label className="form-label">نقش هدف</label>
                    <select className="form-input" value={data.audience_value} onChange={(event) => setData('audience_value', event.target.value)}>
                      {allowedRoles.map((role) => (
                        <option key={role} value={role}>{roleLabels[role] ?? role}</option>
                      ))}
                    </select>
                  </div>
                )}

                {data.audience_type === 'classroom' && (
                  <div className="form-group">
                    <label className="form-label">کلاس هدف</label>
                    <select className="form-input" value={data.audience_value} onChange={(event) => setData('audience_value', event.target.value)} required>
                      <option value="">انتخاب کلاس</option>
                      {classrooms.map((classroom) => <option key={classroom.id} value={String(classroom.id)}>{classroom.name}</option>)}
                    </select>
                  </div>
                )}

                {data.audience_type === 'user' && (
                  <div className="form-group">
                    <label className="form-label">کاربر هدف</label>
                    <select className="form-input" value={data.audience_value} onChange={(event) => setData('audience_value', event.target.value)} required>
                      <option value="">انتخاب کاربر</option>
                      {users.map((user) => <option key={user.id} value={String(user.id)}>{user.name} - {roleLabels[user.role] ?? user.role}</option>)}
                    </select>
                  </div>
                )}
              </div>

              <label className="news-check">
                <input type="checkbox" checked={data.is_important} onChange={(event) => setData('is_important', event.target.checked)} />
                <span>
                  <strong>کارت مهم با ضربان ملایم</strong>
                  <small>برای خبرهای مهم، کارت در داشبورد برجسته‌تر دیده می‌شود.</small>
                </span>
              </label>

              <div className="action-row">
                <button className="btn btn-primary" type="submit" disabled={processing}>
                  <i className="bi bi-send" /> {processing ? 'در حال ارسال...' : 'ارسال خبر'}
                </button>
                <button className="btn btn-ghost" type="button" onClick={() => setShowForm(false)}>انصراف</button>
              </div>
            </form>

            <aside className="news-preview-panel">
              <span className="news-kicker">پیش‌نمایش زنده</span>
              <NewsVisualCard
                title={data.title || 'عنوان خبر'}
                body={data.body || 'متن خبر اینجا دیده می‌شود. می‌توانید متن برجسته، لینک، رنگ و تصویر اضافه کنید.'}
                imagePath={imagePreview}
                template={data.template}
                color={data.accent_color}
                important={data.is_important}
                layout={layout}
                meta={audienceLabel(data.audience_type, data.audience_value, classrooms, users)}
              />
            </aside>
          </section>
        )}

        <section className="panel-card news-list-panel">
          <div className="news-list-head">
            <div>
              <h3>خبرهای ارسال‌شده</h3>
              <p>{news.length} خبر در این مدرسه ثبت شده است.</p>
            </div>
          </div>

          {news.length === 0 ? (
            <div className="news-empty">
              <i className="bi bi-newspaper" />
              <strong>هنوز خبری ارسال نشده</strong>
              <span>از دکمه «خبر جدید» اولین کارت داشبورد را بسازید.</span>
            </div>
          ) : (
            <div className="news-list">
              {news.map((item) => (
                <NewsCard
                  key={item.id}
                  item={item}
                  classrooms={classrooms}
                  users={users}
                  onDelete={() => destroy(item.id)}
                />
              ))}
            </div>
          )}
        </section>
      </div>
    </AppLayout>
  );
}

function renderRichText(text: string): ReactNode[] {
  const nodes: ReactNode[] = [];
  const pattern = /(\*\*([^*]+)\*\*)|(\[([^\]]+)\]\((https?:\/\/[^)\s]+)\))/g;
  let lastIndex = 0;
  let match: RegExpExecArray | null;

  while ((match = pattern.exec(text)) !== null) {
    if (match.index > lastIndex) nodes.push(text.slice(lastIndex, match.index));
    if (match[2]) nodes.push(<strong key={`b-${match.index}`}>{match[2]}</strong>);
    if (match[4] && match[5]) {
      nodes.push(<a key={`a-${match.index}`} href={match[5]} target="_blank" rel="noreferrer">{match[4]}</a>);
    }
    lastIndex = pattern.lastIndex;
  }

  if (lastIndex < text.length) nodes.push(text.slice(lastIndex));
  return nodes;
}

function NewsVisualCard({
  title,
  body,
  imagePath,
  template,
  color,
  important,
  layout,
  meta,
}: {
  title: string;
  body: string;
  imagePath: string | null;
  template: string;
  color: string;
  important: boolean;
  layout: Required<NewsLayout>;
  meta: string;
}) {
  const tpl = templates[template] ?? templates.info;

  return (
    <article
      className={[
        'news-visual-card',
        important ? 'news-visual-card--pulse' : '',
        layout.align === 'center' ? 'news-visual-card--center' : '',
        layout.density === 'compact' ? 'news-visual-card--compact' : '',
      ].filter(Boolean).join(' ')}
      style={{ '--news-color': color, '--news-bg': tpl.bg } as CSSProperties}
    >
      {imagePath && <img className="news-visual-image" src={imagePath.startsWith('blob:') ? imagePath : `/storage/${imagePath}`} alt="" />}
      <div className="news-visual-content">
        <div className="news-visual-top">
          <span className="news-visual-icon"><i className={`bi ${tpl.icon}`} /></span>
          {layout.badge && <span className="news-visual-badge">{layout.badge}</span>}
          {important && <span className="news-visual-badge news-visual-badge--hot">مهم</span>}
        </div>
        <h3>{title}</h3>
        <p>{renderRichText(body)}</p>
        <div className="news-visual-meta">
          <span><i className="bi bi-bullseye" /> {meta}</span>
        </div>
        {layout.linkText && layout.linkUrl && (
          <a className="news-visual-link" href={layout.linkUrl} target="_blank" rel="noreferrer">
            {layout.linkText}
            <i className="bi bi-arrow-left" />
          </a>
        )}
      </div>
    </article>
  );
}

function NewsCard({ item, classrooms, users, onDelete }: { item: NewsItem; classrooms: Classroom[]; users: User[]; onDelete: () => void }) {
  const layout = parseLayout(item.layout);
  const tpl = templates[item.template] ?? templates.info;
  const color = item.accentColor || tpl.color;

  return (
    <div className="news-row-card">
      <NewsVisualCard
        title={item.title}
        body={item.body}
        imagePath={item.imagePath}
        template={item.template}
        color={color}
        important={item.isImportant}
        layout={layout}
        meta={audienceLabel(item.audienceType, item.audienceValue, classrooms, users)}
      />
      <div className="news-row-meta">
        <span><i className="bi bi-eye" /> {item.readCount} خوانده</span>
        <span><i className="bi bi-person" /> {item.sender}</span>
        <span><i className="bi bi-clock" /> {item.createdAt}</span>
        {item.expiresAt && <span><i className="bi bi-calendar-x" /> انقضا: {item.expiresAt}</span>}
        <button className="news-delete-btn" type="button" onClick={onDelete} title="حذف خبر">
          <i className="bi bi-trash3" />
        </button>
      </div>
    </div>
  );
}
