"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Progress } from "@/components/ui/progress";
import { useToast } from "@/hooks/use-toast";
import { apiFetch } from "@/lib/client-utils";
import { SchoolSettingsDTO } from "@/lib/types";
import {
  Settings, Loader2, Upload, Building2, Save, Trash2, Download, Database,
  RefreshCw, PackageCheck, ShieldCheck, CircleAlert,
} from "lucide-react";

/** حالات عملية التحديث كما تصل من /api/system/update-status */
type UpdateStage = "idle" | "stopping-server" | "backing-up-data" | "swapping-files" | "database-sync" | "restarting-server" | "success" | "failed";

const STAGE_LABELS: Record<UpdateStage, string> = {
  idle: "لا توجد عملية جارية",
  "stopping-server": "إيقاف الخادم بأمان...",
  "backing-up-data": "حفظ نسخة احتياطية من البيانات وفحصها...",
  "swapping-files": "تبديل ملفات النظام...",
  "database-sync": "مزامنة قاعدة البيانات (إضافة آمنة فقط)...",
  "restarting-server": "إعادة تشغيل النظام...",
  success: "تم التحديث بنجاح",
  failed: "فشل التحديث",
};

interface DatabaseBackupSummary {
  id: string;
  createdAt: string;
  fromVersion: string;
  toVersion: string;
  databaseFile: string;
  databaseBytes: number;
}

export default function SettingsView({
  settings,
  onSettingsChanged,
}: {
  settings: SchoolSettingsDTO | null;
  onSettingsChanged: () => void;
}) {
  const { toast } = useToast();
  const [nameAr, setNameAr] = useState(settings?.nameAr ?? "");
  const [nameEn, setNameEn] = useState(settings?.nameEn ?? "");
  const [logo, setLogo] = useState<string | null>(settings?.logoData ?? null);
  const [address, setAddress] = useState(settings?.address ?? "");
  const [phone, setPhone] = useState(settings?.phone ?? "");
  const [email, setEmail] = useState(settings?.email ?? "");
  const [currency, setCurrency] = useState(settings?.currency ?? "د.ع");
  const [footerText, setFooterText] = useState(settings?.footerText ?? "");
  const [saving, setSaving] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  /* ───── التحديث الذاتي ───── */
  const [currentVersion, setCurrentVersion] = useState("...");
  const [releaseName, setReleaseName] = useState("");
  const [upFile, setUpFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [uploadProgress, setUploadProgress] = useState(0);
  const [upStage, setUpStage] = useState<UpdateStage>("idle");
  const [upMessage, setUpMessage] = useState("");
  const [dataBackupPath, setDataBackupPath] = useState("");
  const [backups, setBackups] = useState<DatabaseBackupSummary[]>([]);
  const upFileRef = useRef<HTMLInputElement>(null);

  const loadBackups = useCallback(async () => {
    try {
      const result = await apiFetch<{ backups: DatabaseBackupSummary[] }>("/api/system/backups");
      setBackups(result.backups);
    } catch {
      setBackups([]);
    }
  }, []);

  useEffect(() => {
    loadBackups();
  }, [loadBackups]);

  // قراءة الإصدار الحالي
  useEffect(() => {
    apiFetch<{ version: string; releaseName: string }>("/api/system/version")
      .then((v) => {
        setCurrentVersion(v.version);
        setReleaseName(v.releaseName ?? "");
      })
      .catch(() => setCurrentVersion("؟"));
  }, []);

  // متابعة حالة التحديث أثناء التنفيذ (وخلال إعادة التشغيل نكمل المحاولة)
  useEffect(() => {
    if (upStage === "idle" || upStage === "success" || upStage === "failed") return;
    let stopped = false;
    const tick = async () => {
      try {
        const st = await apiFetch<{ stage: UpdateStage; message: string; error?: string; databaseBackupPath?: string }>("/api/system/update-status");
        if (stopped) return;
        setUpStage(st.stage);
        setUpMessage(st.message ?? "");
        if (st.databaseBackupPath) setDataBackupPath(st.databaseBackupPath);
        if (st.stage === "success") {
          const v = await apiFetch<{ version: string; releaseName: string }>("/api/system/version").catch(() => null);
          if (v) { setCurrentVersion(v.version); setReleaseName(v.releaseName ?? ""); }
          loadBackups();
          onSettingsChanged();
        }
      } catch {
        // الخادم قد يكون يعيد التشغيل — نتابع
      }
    };
    const iv = setInterval(tick, 2000);
    tick();
    return () => { stopped = true; clearInterval(iv); };
  }, [upStage, onSettingsChanged, loadBackups]);

  function pickUpdateFile(e: React.ChangeEvent<HTMLInputElement>) {
    const f = e.target.files?.[0] ?? null;
    if (f && !f.name.toLowerCase().endsWith(".zip")) {
      toast({ title: "ملف غير صالح", description: "يجب أن تكون الحزمة ملف ZIP", variant: "destructive" });
      return;
    }
    setUpFile(f);
  }

  function startUpdate() {
    if (!upFile || uploading) return;
    setUploading(true);
    setUploadProgress(0);
    setUpStage("stopping-server");
    setUpMessage("جارٍ رفع الحزمة والتحقق منها...");

    // رفع يدوي بـ XHR لمتابعة نسبة التقدم
    const xhr = new XMLHttpRequest();
    xhr.open("POST", "/api/system/update");
    xhr.upload.onprogress = (e) => {
      if (e.lengthComputable) setUploadProgress(Math.round((e.loaded / e.total) * 100));
    };
    xhr.onload = () => {
      setUploading(false);
      try {
        const res = JSON.parse(xhr.responseText);
        if (xhr.status >= 200 && xhr.status < 300 && res.ok) {
          setUploadProgress(100);
          toast({
            title: "تم قبول الحزمة — جارٍ التحديث",
            description: "لا تغلق النافذة ولا الصفحة — ستعود الصفحة تلقائياً بعد إعادة التشغيل",
          });
          setUpStage("stopping-server");
        } else {
          setUpStage("failed");
          setUpMessage(res.error ?? "رُفضت الحزمة");
        }
      } catch {
        setUpStage("failed");
        setUpMessage("رد غير مفهوم من الخادم — راجع نافذة التشغيل");
      }
    };
    xhr.onerror = () => {
      // انقطاع الرد قد يعني أن الخادم أُعيد تشغيله بالفعل — نتابع الحالة
      setUploading(false);
      setUpStage("restarting-server");
      setUpMessage("انقطع الاتصال أثناء التطبيق — نتابع فحص الحالة...");
    };
    const fd = new FormData();
    fd.append("file", upFile);
    xhr.send(fd);
  }

  function handleLogo(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;
    if (!file.type.startsWith("image/")) {
      toast({ title: "ملف غير صالح", description: "يجب أن يكون الشعار صورة (PNG / JPG / SVG)", variant: "destructive" });
      return;
    }
    if (file.size > 1.5 * 1024 * 1024) {
      toast({ title: "الصورة كبيرة", description: "الحد الأقصى لحجم الشعار 1.5 ميجابايت", variant: "destructive" });
      return;
    }
    const reader = new FileReader();
    reader.onload = () => setLogo(reader.result as string);
    reader.readAsDataURL(file);
  }

  async function save(e: React.FormEvent) {
    e.preventDefault();
    if (nameAr.trim().length < 2) {
      toast({ title: "اسم المدرسة بالعربية مطلوب", variant: "destructive" });
      return;
    }
    setSaving(true);
    try {
      await apiFetch("/api/settings", {
        method: "PUT",
        body: JSON.stringify({
          nameAr: nameAr.trim(),
          nameEn: nameEn.trim(),
          logoData: logo ?? "",
          address,
          phone,
          email,
          currency,
          footerText,
        }),
      });
      toast({ title: "تم حفظ الإعدادات", description: "ستظهر التغييرات في الشعار والوصولات والتقارير فوراً" });
      onSettingsChanged();
    } catch (err) {
      toast({ title: "فشل الحفظ", description: err instanceof Error ? err.message : "", variant: "destructive" });
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="space-y-5 max-w-3xl">
      {/* تحديث النظام */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-lg flex items-center gap-2">
            <RefreshCw className="w-5 h-5 text-primary" />
            تحديث النظام
          </CardTitle>
          <CardDescription>
            الإصدار الحالي: <span className="font-bold text-foreground" dir="ltr">v{currentVersion}</span>
            {releaseName ? <span> — {releaseName}</span> : null}
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          {upStage === "idle" || upStage === "failed" ? (
            <>
              <div className="rounded-xl border border-dashed p-4 space-y-3">
                <div className="flex items-center gap-2 text-sm">
                  <ShieldCheck className="w-4 h-4 text-emerald-600" />
                  تُحفظ نسخة مؤرخة ومفحوصة خارج مجلد التطبيق قبل التحديث، وتبقى النسخ السابقة متاحة للاسترجاع
                </div>
                <input
                  ref={upFileRef}
                  type="file"
                  accept=".zip"
                  className="hidden"
                  onChange={pickUpdateFile}
                />
                <div className="flex flex-wrap items-center gap-2">
                  <Button type="button" variant="outline" onClick={() => upFileRef.current?.click()}>
                    <PackageCheck className="w-4 h-4 ml-1" />
                    اختيار حزمة التحديث (ZIP)
                  </Button>
                  {upFile && <span className="text-sm text-muted-foreground truncate max-w-[240px]">{upFile.name}</span>}
                </div>
                {upFile && uploading && (
                  <div className="space-y-1">
                    <Progress value={uploadProgress} />
                    <p className="text-xs text-muted-foreground">جارٍ الرفع... {uploadProgress}%</p>
                  </div>
                )}
                {upStage === "failed" && (
                  <div className="flex items-start gap-2 rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
                    <CircleAlert className="w-4 h-4 mt-0.5 shrink-0" />
                    <span>{upMessage || "فشل التحديث — راجع update-log.txt في مجلد النظام"}</span>
                  </div>
                )}
                <Button className="w-full sm:w-56 h-11 font-bold" disabled={!upFile || uploading} onClick={startUpdate}>
                  {uploading ? <Loader2 className="w-4 h-4 ml-2 animate-spin" /> : <RefreshCw className="w-4 h-4 ml-2" />}
                  {uploading ? "جارٍ الرفع..." : "تطبيق التحديث الآن"}
                </Button>
              </div>
            </>
          ) : (
            <div className="rounded-xl border p-4 space-y-2">
              <div className="flex items-center gap-2 text-sm font-medium">
                {upStage === "success" ? (
                  <><PackageCheck className="w-5 h-5 text-emerald-600" /> {upMessage || STAGE_LABELS[upStage]}</>
                ) : (
                  <><Loader2 className="w-5 h-5 animate-spin text-primary" /> {STAGE_LABELS[upStage]}</>
                )}
              </div>
              {upMessage && upStage !== "success" && <p className="text-xs text-muted-foreground">{upMessage}</p>}
              {dataBackupPath && (
                <div className="rounded-lg bg-primary/5 p-3 text-xs text-muted-foreground" dir="ltr">
                  <span className="font-semibold text-foreground">Database backup:</span> {dataBackupPath}
                </div>
              )}
              {upStage === "success" && (
                <p className="text-xs text-muted-foreground">
                  إذا لم تُحدّث الصفحة تلقائياً خلال لحظات أعد تحميلها (F5) — الإصدار الجديد: v{currentVersion}
                </p>
              )}
            </div>
          )}
        </CardContent>
      </Card>

      {/* النسخ الاحتياطية لقاعدة البيانات */}
      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-lg flex items-center gap-2">
            <Database className="w-5 h-5 text-primary" />
            النسخ الاحتياطية للبيانات
          </CardTitle>
          <CardDescription>
            تُنشأ نسخة سليمة قبل كل تحديث من داخل النظام، وتُحفظ خارج مجلد التطبيق.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          {backups.length === 0 ? (
            <div className="rounded-xl border border-dashed p-4 text-sm text-muted-foreground">
              لا توجد نسخ تلقائية بعد. سيُنشأ أول ملف عند تطبيق تحديث من داخل النظام.
            </div>
          ) : (
            <div className="space-y-2">
              {backups.slice(0, 8).map((backup) => (
                <div key={backup.id} className="flex flex-col gap-3 rounded-xl border bg-muted/20 p-3 sm:flex-row sm:items-center sm:justify-between">
                  <div className="min-w-0">
                    <p className="text-sm font-semibold">
                      {backup.createdAt ? new Intl.DateTimeFormat("ar-IQ-u-nu-latn", { dateStyle: "medium", timeStyle: "short" }).format(new Date(backup.createdAt)) : backup.id}
                    </p>
                    <p className="mt-1 text-xs text-muted-foreground" dir="ltr">
                      {backup.databaseFile} · {(backup.databaseBytes / (1024 * 1024)).toFixed(2)} MB · v{backup.fromVersion} → v{backup.toVersion}
                    </p>
                  </div>
                  <Button
                    type="button"
                    variant="outline"
                    className="w-full shrink-0 sm:w-auto"
                    onClick={() => window.location.assign(`/api/system/backups?download=${encodeURIComponent(backup.id)}`)}
                  >
                    <Download className="h-4 w-4" />
                    تنزيل النسخة
                  </Button>
                </div>
              ))}
            </div>
          )}
          <p className="text-xs leading-6 text-muted-foreground">
            للاسترجاع عند الضرورة: أوقف التطبيق، واحتفظ بنسخة من قاعدة البيانات الحالية، ثم أعد ملف النسخة إلى مسار قاعدة البيانات المحدد في إعداد التطبيق وشغّله مجددًا.
          </p>
        </CardContent>
      </Card>

      <Card>
        <CardHeader className="pb-3">
          <CardTitle className="text-lg flex items-center gap-2">
            <Settings className="w-5 h-5 text-primary" />
            إعدادات المدرسة
          </CardTitle>
          <CardDescription>تخصيص بيانات المدرسة التي تظهر في القائمة الجانبية ووصلات الدفع والتقارير</CardDescription>
        </CardHeader>
        <CardContent>
          <form onSubmit={save} className="space-y-5">
            {/* الشعار */}
            <div className="rounded-xl border border-dashed p-4 flex flex-col sm:flex-row items-center gap-4">
              <div className="w-20 h-20 rounded-2xl border bg-muted/50 flex items-center justify-center overflow-hidden shrink-0">
                {logo ? (
                  <img src={logo} alt="شعار المدرسة" className="w-full h-full object-contain" />
                ) : (
                  <Building2 className="w-8 h-8 text-muted-foreground" />
                )}
              </div>
              <div className="flex-1 text-center sm:text-right">
                <p className="font-semibold text-sm mb-1">شعار المدرسة (Logo)</p>
                <p className="text-xs text-muted-foreground mb-2">
                  يظهر تلقائياً في أعلى الوصولات والتقارير — PNG/JPG/SVG حتى 1.5MB
                </p>
                <div className="flex items-center justify-center sm:justify-start gap-2">
                  <input ref={fileRef} type="file" accept="image/*" className="hidden" onChange={handleLogo} />
                  <Button type="button" variant="outline" size="sm" onClick={() => fileRef.current?.click()}>
                    <Upload className="w-4 h-4 ml-1" />
                    رفع شعار
                  </Button>
                  {logo && (
                    <Button type="button" variant="ghost" size="sm" className="text-destructive" onClick={() => setLogo(null)}>
                      <Trash2 className="w-4 h-4 ml-1" />
                      إزالة
                    </Button>
                  )}
                </div>
              </div>
            </div>

            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="s-nameAr">اسم المدرسة بالعربية *</Label>
                <Input id="s-nameAr" value={nameAr} onChange={(e) => setNameAr(e.target.value)} required />
              </div>
              <div className="space-y-2">
                <Label htmlFor="s-nameEn">اسم المدرسة بالإنجليزية</Label>
                <Input id="s-nameEn" value={nameEn} onChange={(e) => setNameEn(e.target.value)} dir="ltr" className="text-left" />
              </div>
            </div>

            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <Label htmlFor="s-phone">رقم الهاتف</Label>
                <Input id="s-phone" value={phone} onChange={(e) => setPhone(e.target.value)} dir="ltr" className="text-left" placeholder="07XX XXX XXXX" />
              </div>
              <div className="space-y-2">
                <Label htmlFor="s-email">البريد الإلكتروني</Label>
                <Input id="s-email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} dir="ltr" className="text-left" />
              </div>
            </div>

            <div className="space-y-2">
              <Label htmlFor="s-address">العنوان</Label>
              <Input id="s-address" value={address} onChange={(e) => setAddress(e.target.value)} />
            </div>

            <div className="grid gap-4 sm:grid-cols-[160px_1fr]">
              <div className="space-y-2">
                <Label htmlFor="s-currency">رمز العملة</Label>
                <Input id="s-currency" value={currency} onChange={(e) => setCurrency(e.target.value)} className="font-bold" />
              </div>
              <div className="space-y-2">
                <Label htmlFor="s-footer">التذييل الخطي للوصولات (Footer)</Label>
                <Textarea
                  id="s-footer"
                  rows={2}
                  value={footerText}
                  onChange={(e) => setFooterText(e.target.value)}
                  placeholder="مثال: شكراً لتعاملكم معنا — هذه الوصل إثبات دفع ولا يُعتد به دون الختم الرسمي"
                />
              </div>
            </div>

            <Button type="submit" className="w-full sm:w-48 h-11 font-bold" disabled={saving}>
              {saving ? <Loader2 className="w-4 h-4 ml-2 animate-spin" /> : <Save className="w-4 h-4 ml-2" />}
              {saving ? "جارٍ الحفظ..." : "حفظ الإعدادات"}
            </Button>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}
