import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import { PlusIcon, TrashIcon } from '@heroicons/react/24/outline';
import PageHeader from '../components/ui/PageHeader';
import SearchableSelect from '../components/ui/SearchableSelect';
import { usePermissions } from '../hooks/usePermissions';
import { useBranchWorkingHours, useBranches } from '../hooks/useBranches';
import type { WorkingHourRange } from '../types';
import SettingsLayout from '../components/layout/SettingsLayout';

/** ۰ = شنبه — همان قرارداد محاسبهٔ اسلات در بک‌اند. */
const DAY_LABELS = ['شنبه', 'یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه'];

const MINUTES_IN_DAY = 1440;

/**
 * `endOfDay` وجود دارد چون `<input type="time">` سقفش ۲۳:۵۹ است و مقدار ۲۴:۰۰ را
 * نه نشان می‌دهد و نه می‌سازد. بدون این پرچم، بازهٔ شبانه‌روزیِ ذخیره‌شده (۱۴۴۰)
 * بی‌صدا از فرم می‌افتاد و اولین ذخیره آن را خراب می‌کرد.
 */
type Draft = { start: string; end: string; endOfDay: boolean };

function toTime(minute: number): string {
  return `${String(Math.floor(minute / 60)).padStart(2, '0')}:${String(minute % 60).padStart(2, '0')}`;
}

/** `"24:00"` باید ۱۴۴۰ بدهد نه صفر — پایان روز است، نه آغازش. */
function toMinutes(time: string): number | null {
  const m = /^(\d{1,2}):(\d{2})$/.exec(time.trim());
  if (!m) return null;
  const minutes = Number(m[1]) * 60 + Number(m[2]);
  return minutes >= 0 && minutes <= MINUTES_IN_DAY ? minutes : null;
}

/**
 * ساعت کاری هفتگی یک شعبه.
 *
 * ذخیره یک PUT است و کل هفته را جایگزین می‌کند؛ روزِ خالی یعنی شعبه آن روز بسته
 * است. اعتبارسنجی نهایی سمت سرور است — این فرم فقط جلوی ارسال ورودی واضحاً خراب
 * را می‌گیرد تا کاربر منتظر رفت‌وبرگشت نماند.
 */
export default function BranchWorkingHoursPage() {
  const { branchUuid } = useParams<{ branchUuid: string }>();
  const { workingHours, loading, save } = useBranchWorkingHours(branchUuid);
  const { branches } = useBranches();
  const { can } = usePermissions();
  const canUpdate = can('appointment_settings', 'update');

  const branch = branches.find((b) => b.uuid === branchUuid);

  const [draft, setDraft] = useState<Record<number, Draft[]>>({});
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!workingHours) return;
    const next: Record<number, Draft[]> = {};
    DAY_LABELS.forEach((_, day) => {
      next[day] = (workingHours.days[String(day)] ?? []).map((r: WorkingHourRange) => ({
        start: toTime(r.start_minute),
        end: r.end_minute === MINUTES_IN_DAY ? '23:59' : toTime(r.end_minute),
        endOfDay: r.end_minute === MINUTES_IN_DAY,
      }));
    });
    setDraft(next);
  }, [workingHours]);

  const addRange = (day: number) => {
    setDraft((d) => ({ ...d, [day]: [...(d[day] ?? []), { start: '09:00', end: '13:00', endOfDay: false }] }));
  };

  const removeRange = (day: number, index: number) => {
    setDraft((d) => ({ ...d, [day]: (d[day] ?? []).filter((_, i) => i !== index) }));
  };

  const editRange = (day: number, index: number, patch: Partial<Draft>) => {
    setDraft((d) => ({
      ...d,
      [day]: (d[day] ?? []).map((r, i) => (i === index ? { ...r, ...patch } : r)),
    }));
  };

  const copyToWholeWeek = (day: number) => {
    const source = draft[day] ?? [];
    const next: Record<number, Draft[]> = {};
    DAY_LABELS.forEach((_, d) => { next[d] = source.map((r) => ({ ...r })); });
    setDraft(next);
  };

  const submit = () => {
    const days: Record<string, { start_minute: number; end_minute: number }[]> = {};

    for (const [dayKey, ranges] of Object.entries(draft)) {
      const parsed: { start_minute: number; end_minute: number }[] = [];

      for (const range of ranges) {
        const start = toMinutes(range.start);
        const end = range.endOfDay ? MINUTES_IN_DAY : toMinutes(range.end);

        if (start === null || end === null) {
          setError(`ساعت روز ${DAY_LABELS[Number(dayKey)]} را به شکل ۰۹:۰۰ وارد کنید`);
          return;
        }
        if (end <= start) {
          setError(`در روز ${DAY_LABELS[Number(dayKey)]} پایان بازه باید بعد از شروع آن باشد`);
          return;
        }
        parsed.push({ start_minute: start, end_minute: end });
      }

      days[dayKey] = parsed;
    }

    setError(null);
    save.mutate(days);
  };

  const totalRanges = Object.values(draft).reduce((sum, ranges) => sum + ranges.length, 0);

  return (
    <SettingsLayout active="branches">
      <div className="fade-in">
        <PageHeader
          title={`ساعت کاری ${branch?.name ?? 'شعبه'}`}
          description="روز بدون بازه یعنی شعبه آن روز بسته است. شعبهٔ بدون هیچ ساعتی «تعریف‌نشده» است، نه همیشه‌باز."
          backTo="/admin/branches"
          breadcrumbs={[
            { label: 'شعبه‌ها', to: '/admin/branches' },
            { label: 'ساعت کاری' },
          ]}
          action={
            canUpdate ? (
              <button type="button" className="btn primary" disabled={save.isPending} onClick={submit}>
                {save.isPending ? 'در حال ذخیره...' : 'ذخیرهٔ هفته'}
              </button>
            ) : undefined
          }
        />

        {error && (
          <div
            className="card"
            style={{ padding: '12px 16px', marginBottom: 16, color: 'var(--danger)', background: 'var(--danger-bg)', fontSize: 13 }}
          >
            {error}
          </div>
        )}

        {branch && canUpdate && (
          <div className="card" style={{ padding: 16, marginBottom: 16, display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
            <span style={{ fontSize: 13, color: 'var(--text-2)' }}>منطقهٔ زمانی شعبه</span>
            <div style={{ minWidth: 240 }}>
              <TimezoneSelect branchUuid={branch.uuid} value={branch.timezone} />
            </div>
            <span style={{ fontSize: 12, color: 'var(--text-3)' }}>
              {totalRanges === 0 ? 'هیچ بازه‌ای تعریف نشده' : `${totalRanges} بازه در هفته`}
            </span>
          </div>
        )}

        {loading ? (
          <div style={{ padding: 16, color: 'var(--text-3)', fontSize: 13 }}>در حال بارگذاری...</div>
        ) : (
          <div style={{ display: 'grid', gap: 12 }}>
            {DAY_LABELS.map((label, day) => {
              const ranges = draft[day] ?? [];
              return (
                <div key={day} className="card" style={{ padding: 16 }}>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: ranges.length ? 12 : 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                      <span style={{ fontWeight: 700, fontSize: 14 }}>{label}</span>
                      {ranges.length === 0 && (
                        <span style={{ fontSize: 12, color: 'var(--text-3)' }}>بسته</span>
                      )}
                    </div>
                    {canUpdate && (
                      <div style={{ display: 'flex', gap: 6 }}>
                        {ranges.length > 0 && (
                          <button type="button" className="btn secondary sm" onClick={() => copyToWholeWeek(day)}>
                            اعمال روی همهٔ روزها
                          </button>
                        )}
                        <button type="button" className="btn secondary sm" onClick={() => addRange(day)}>
                          <PlusIcon style={{ width: 15 }} /> بازه
                        </button>
                      </div>
                    )}
                  </div>

                  <div style={{ display: 'grid', gap: 8 }}>
                    {ranges.map((range, index) => (
                      <div key={index} style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
                        <label style={{ fontSize: 12, color: 'var(--text-3)' }}>از</label>
                        <input
                          type="time"
                          className="field"
                          value={range.start}
                          disabled={!canUpdate}
                          onChange={(e) => editRange(day, index, { start: e.target.value })}
                          style={{ width: 120 }}
                        />
                        <label style={{ fontSize: 12, color: 'var(--text-3)' }}>تا</label>
                        {range.endOfDay ? (
                          <span className="field" style={{ width: 120, color: 'var(--text-2)' }}>۲۴:۰۰</span>
                        ) : (
                          <input
                            type="time"
                            className="field"
                            value={range.end}
                            disabled={!canUpdate}
                            onChange={(e) => editRange(day, index, { end: e.target.value })}
                            style={{ width: 120 }}
                          />
                        )}
                        <label style={{ display: 'flex', alignItems: 'center', gap: 5, fontSize: 12, color: 'var(--text-3)' }}>
                          <input
                            type="checkbox"
                            checked={range.endOfDay}
                            disabled={!canUpdate}
                            onChange={(e) => editRange(day, index, { endOfDay: e.target.checked })}
                          />
                          تا پایان روز
                        </label>
                        {canUpdate && (
                          <button
                            type="button"
                            className="btn secondary sm"
                            onClick={() => removeRange(day, index)}
                            aria-label="حذف بازه"
                          >
                            <TrashIcon style={{ width: 15 }} />
                          </button>
                        )}
                      </div>
                    ))}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </SettingsLayout>
  );
}

/**
 * فهرست منطقهٔ زمانی کوتاه و ثابت است — بک‌اند با `DateTimeZone::listIdentifiers()`
 * اعتبارسنجی می‌کند، پس این فهرست تنها راحتی است و منبع حقیقت نیست.
 */
const TIMEZONES = ['Asia/Tehran', 'Asia/Dubai', 'Asia/Baghdad', 'Europe/Istanbul', 'UTC'];

function TimezoneSelect({ branchUuid, value }: { branchUuid: string; value: string }) {
  const { update } = useBranches();
  const options = TIMEZONES.includes(value) ? TIMEZONES : [value, ...TIMEZONES];

  return (
    <SearchableSelect
      options={options.map((tz) => ({ value: tz, label: tz }))}
      value={value}
      onChange={(v) => v && update.mutate({ uuid: branchUuid, d: { timezone: String(v) } })}
      placeholder="منطقهٔ زمانی"
      height={38}
    />
  );
}
