'use client';

import Link from 'next/link';
import { useCallback, useEffect, useMemo, useState } from 'react';
import type { BackgroundJobLog, RecurringExpenseTemplate, RecurringScheduleJob, SchedulerStatus } from '@/lib/types';
import { Badge } from '@/components/ui/badge';
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 { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
import { useToast } from '@/hooks/use-toast';

type Props = {
  templates: RecurringExpenseTemplate[];
};

type JobStatusFilter = 'all' | 'active' | 'paused' | 'completed' | 'cancelled';
type LogStatusFilter = 'all' | 'pending' | 'running' | 'success' | 'failed' | 'retry';

function toLocal(value?: string) {
  if (!value) return '-';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '-';
  return date.toLocaleString('ar-SA');
}

function shortId(value: string) {
  if (!value) return '-';
  return value.length > 16 ? `${value.slice(0, 10)}...${value.slice(-4)}` : value;
}

export function ExpenseSchedulerDashboard({ templates }: Props) {
  const { toast } = useToast();

  const [status, setStatus] = useState<SchedulerStatus | null>(null);
  const [jobs, setJobs] = useState<RecurringScheduleJob[]>([]);
  const [logs, setLogs] = useState<BackgroundJobLog[]>([]);

  const [jobStatusFilter, setJobStatusFilter] = useState<JobStatusFilter>('all');
  const [logStatusFilter, setLogStatusFilter] = useState<LogStatusFilter>('all');
  const [selectedTemplateId, setSelectedTemplateId] = useState<string>('all');

  const [jobsLimit, setJobsLimit] = useState('50');
  const [logsLimit, setLogsLimit] = useState('50');

  const [loading, setLoading] = useState(false);
  const [runningAction, setRunningAction] = useState(false);

  const templateMap = useMemo(() => {
    const map = new Map<string, RecurringExpenseTemplate>();
    templates.forEach((t) => map.set(t.id, t));
    return map;
  }, [templates]);

  const fetchAll = useCallback(async () => {
    setLoading(true);
    try {
      const jobsParams = new URLSearchParams();
      if (jobStatusFilter !== 'all') jobsParams.set('status', jobStatusFilter);
      if (selectedTemplateId !== 'all') jobsParams.set('templateId', selectedTemplateId);
      jobsParams.set('limit', String(Math.max(1, Number(jobsLimit) || 50)));

      const logsParams = new URLSearchParams();
      if (logStatusFilter !== 'all') logsParams.set('status', logStatusFilter);
      logsParams.set('limit', String(Math.max(1, Number(logsLimit) || 50)));

      const [statusRes, jobsRes, logsRes] = await Promise.all([
        fetch('/api/admin/expense-recurring/scheduler/status', { cache: 'no-store' }),
        fetch(`/api/admin/expense-recurring/scheduler/jobs?${jobsParams.toString()}`, { cache: 'no-store' }),
        fetch(`/api/admin/expense-recurring/scheduler/logs?${logsParams.toString()}`, { cache: 'no-store' }),
      ]);

      if (!statusRes.ok) throw new Error('تعذر تحميل حالة المجدول');
      if (!jobsRes.ok) throw new Error('تعذر تحميل الوظائف');
      if (!logsRes.ok) throw new Error('تعذر تحميل السجلات');

      const statusData = await statusRes.json();
      const jobsData = await jobsRes.json();
      const logsData = await logsRes.json();

      setStatus(statusData as SchedulerStatus);
      setJobs(Array.isArray(jobsData?.items) ? (jobsData.items as RecurringScheduleJob[]) : []);
      setLogs(Array.isArray(logsData?.items) ? (logsData.items as BackgroundJobLog[]) : []);
    } catch (error) {
      toast({
        title: 'خطأ',
        description: error instanceof Error ? error.message : 'فشل تحميل بيانات المجدول',
        variant: 'destructive',
      });
    } finally {
      setLoading(false);
    }
  }, [jobStatusFilter, jobsLimit, logStatusFilter, logsLimit, selectedTemplateId, toast]);

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

  const handleToggleScheduler = async (enable: boolean) => {
    setRunningAction(true);
    try {
      const res = await fetch('/api/admin/expense-recurring/scheduler/start', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ enable }),
      });

      if (!res.ok) throw new Error(enable ? 'تعذر تشغيل المجدول' : 'تعذر إيقاف المجدول');

      toast({
        title: 'نجاح',
        description: enable ? 'تم تشغيل المجدول' : 'تم إيقاف المجدول',
      });
      await fetchAll();
    } catch (error) {
      toast({
        title: 'خطأ',
        description: error instanceof Error ? error.message : 'تعذر تغيير حالة المجدول',
        variant: 'destructive',
      });
    } finally {
      setRunningAction(false);
    }
  };

  const handleGenerateAll = async () => {
    setRunningAction(true);
    try {
      const payload: Record<string, string> = {};
      if (selectedTemplateId !== 'all') payload.templateId = selectedTemplateId;

      const res = await fetch('/api/admin/expense-recurring/scheduler/generate-all', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (!res.ok) throw new Error('تعذر تنفيذ التوليد الجماعي');
      const data = await res.json();

      toast({
        title: 'تم التنفيذ',
        description: `تمت معالجة ${data?.jobsEnqueued ?? 0} وظائف`,
      });
      await fetchAll();
    } catch (error) {
      toast({
        title: 'خطأ',
        description: error instanceof Error ? error.message : 'فشل التوليد الجماعي',
        variant: 'destructive',
      });
    } finally {
      setRunningAction(false);
    }
  };

  const handleJobAction = async (jobId: string, action: 'pause' | 'resume' | 'retry' | 'cancel') => {
    setRunningAction(true);
    try {
      const res = await fetch(`/api/admin/expense-recurring/scheduler/jobs/${jobId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ action }),
      });

      if (!res.ok) {
        const payload = await res.json().catch(() => ({}));
        throw new Error(payload?.error || 'تعذر تنفيذ الإجراء على الوظيفة');
      }

      const actionLabel =
        action === 'pause' ? 'تم إيقاف الوظيفة مؤقتا' :
        action === 'resume' ? 'تم استئناف الوظيفة' :
        action === 'retry' ? 'تمت إعادة جدولة الوظيفة للتنفيذ الفوري' :
        'تم إلغاء الوظيفة';

      toast({
        title: 'نجاح',
        description: actionLabel,
      });

      await fetchAll();
    } catch (error) {
      toast({
        title: 'خطأ',
        description: error instanceof Error ? error.message : 'فشل تنفيذ الإجراء',
        variant: 'destructive',
      });
    } finally {
      setRunningAction(false);
    }
  };

  const healthBadge = status?.isHealthy ? 'default' : 'destructive';

  return (
    <div className="space-y-6">
      <Card>
        <CardHeader>
          <CardTitle>لوحة مراقبة المجدول</CardTitle>
          <CardDescription>مراقبة حالة الخدمة، الوظائف المجدولة، وسجلات التنفيذ في الزمن الحقيقي.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex flex-wrap items-center gap-3">
            <Badge variant={status?.isRunning ? 'default' : 'secondary'}>
              {status?.isRunning ? 'Running' : 'Stopped'}
            </Badge>
            <Badge variant={healthBadge}>{status?.isHealthy ? 'Healthy' : 'Unhealthy'}</Badge>
            <Button onClick={() => handleToggleScheduler(true)} disabled={runningAction || status?.isRunning}>
              تشغيل
            </Button>
            <Button variant="outline" onClick={() => handleToggleScheduler(false)} disabled={runningAction || !status?.isRunning}>
              إيقاف
            </Button>
            <Button variant="secondary" onClick={handleGenerateAll} disabled={runningAction}>
              توليد يدوي الآن
            </Button>
            <Button variant="outline" onClick={fetchAll} disabled={loading || runningAction}>
              تحديث
            </Button>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
            <Card>
              <CardHeader className="pb-2">
                <CardDescription>إجمالي الوظائف</CardDescription>
                <CardTitle className="text-2xl">{status?.totalJobs ?? 0}</CardTitle>
              </CardHeader>
            </Card>
            <Card>
              <CardHeader className="pb-2">
                <CardDescription>الوظائف النشطة</CardDescription>
                <CardTitle className="text-2xl">{status?.activeJobs ?? 0}</CardTitle>
              </CardHeader>
            </Card>
            <Card>
              <CardHeader className="pb-2">
                <CardDescription>الوظائف المكتملة</CardDescription>
                <CardTitle className="text-2xl">{status?.completedJobs ?? 0}</CardTitle>
              </CardHeader>
            </Card>
            <Card>
              <CardHeader className="pb-2">
                <CardDescription>الوظائف الفاشلة</CardDescription>
                <CardTitle className="text-2xl">{status?.failedJobs ?? 0}</CardTitle>
              </CardHeader>
            </Card>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-3 gap-3 text-sm text-muted-foreground">
            <div>آخر تشغيل: {toLocal(status?.lastRunAt)}</div>
            <div>آخر فحص: {toLocal(status?.lastCheckAt)}</div>
            <div>الفحص التالي: {toLocal(status?.nextCheckAt)}</div>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>الوظائف المجدولة</CardTitle>
          <CardDescription>عرض الوظائف مع التصفية حسب الحالة والقالب.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          <div className="grid grid-cols-1 md:grid-cols-4 gap-3">
            <div className="space-y-1">
              <Label>حالة الوظيفة</Label>
              <Select value={jobStatusFilter} onValueChange={(v) => setJobStatusFilter(v as JobStatusFilter)}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">الكل</SelectItem>
                  <SelectItem value="active">active</SelectItem>
                  <SelectItem value="paused">paused</SelectItem>
                  <SelectItem value="completed">completed</SelectItem>
                  <SelectItem value="cancelled">cancelled</SelectItem>
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-1">
              <Label>القالب</Label>
              <Select value={selectedTemplateId} onValueChange={setSelectedTemplateId}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">الكل</SelectItem>
                  {templates.map((t) => (
                    <SelectItem key={t.id} value={t.id}>{t.name}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-1">
              <Label>الحد الأقصى</Label>
              <Input value={jobsLimit} onChange={(e) => setJobsLimit(e.target.value)} inputMode="numeric" />
            </div>

            <div className="flex items-end">
              <Button className="w-full" variant="outline" onClick={fetchAll} disabled={loading || runningAction}>
                تطبيق التصفية
              </Button>
            </div>
          </div>

          <div className="border rounded-md overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>ID</TableHead>
                  <TableHead>القالب</TableHead>
                  <TableHead>التشغيل القادم</TableHead>
                  <TableHead>الحالة</TableHead>
                  <TableHead>Retry</TableHead>
                  <TableHead>Total Runs</TableHead>
                  <TableHead>Basis</TableHead>
                  <TableHead>الإجراءات</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {jobs.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={8} className="text-center text-muted-foreground">لا توجد وظائف</TableCell>
                  </TableRow>
                ) : (
                  jobs.map((job) => {
                    const template = templateMap.get(job.templateId);
                    return (
                      <TableRow key={job.id}>
                        <TableCell>{shortId(job.id)}</TableCell>
                        <TableCell>{template?.name || shortId(job.templateId)}</TableCell>
                        <TableCell>{toLocal(job.nextRunDate)}</TableCell>
                        <TableCell>
                          <Badge variant={job.status === 'active' ? 'default' : 'secondary'}>{job.status}</Badge>
                        </TableCell>
                        <TableCell>{job.retryCount} / {job.maxRetries}</TableCell>
                        <TableCell>{job.totalRuns}</TableCell>
                        <TableCell>{job.obligationBasis}</TableCell>
                        <TableCell>
                          <div className="flex flex-wrap items-center gap-2">
                            {job.status === 'active' ? (
                              <Button
                                size="sm"
                                variant="outline"
                                onClick={() => handleJobAction(job.id, 'pause')}
                                disabled={runningAction || loading}
                              >
                                Pause
                              </Button>
                            ) : (
                              <Button
                                size="sm"
                                variant="outline"
                                onClick={() => handleJobAction(job.id, 'resume')}
                                disabled={runningAction || loading}
                              >
                                Resume
                              </Button>
                            )}

                            <Button
                              size="sm"
                              variant="secondary"
                              onClick={() => handleJobAction(job.id, 'retry')}
                              disabled={runningAction || loading}
                            >
                              Retry
                            </Button>

                            <Button asChild size="sm" variant="ghost">
                              <Link href={`/admin/accounting/expense-recurring-advanced/scheduler/${job.id}`}>
                                تفاصيل
                              </Link>
                            </Button>
                          </div>
                        </TableCell>
                      </TableRow>
                    );
                  })
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle>سجلات التشغيل</CardTitle>
          <CardDescription>آخر عمليات الخدمة مع نتيجة كل تنفيذ.</CardDescription>
        </CardHeader>
        <CardContent className="space-y-3">
          <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
            <div className="space-y-1">
              <Label>حالة السجل</Label>
              <Select value={logStatusFilter} onValueChange={(v) => setLogStatusFilter(v as LogStatusFilter)}>
                <SelectTrigger><SelectValue /></SelectTrigger>
                <SelectContent>
                  <SelectItem value="all">الكل</SelectItem>
                  <SelectItem value="pending">pending</SelectItem>
                  <SelectItem value="running">running</SelectItem>
                  <SelectItem value="success">success</SelectItem>
                  <SelectItem value="failed">failed</SelectItem>
                  <SelectItem value="retry">retry</SelectItem>
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-1">
              <Label>الحد الأقصى</Label>
              <Input value={logsLimit} onChange={(e) => setLogsLimit(e.target.value)} inputMode="numeric" />
            </div>

            <div className="flex items-end">
              <Button className="w-full" variant="outline" onClick={fetchAll} disabled={loading || runningAction}>
                تطبيق التصفية
              </Button>
            </div>
          </div>

          <div className="border rounded-md overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>الوقت</TableHead>
                  <TableHead>Job</TableHead>
                  <TableHead>Type</TableHead>
                  <TableHead>الحالة</TableHead>
                  <TableHead>Generated</TableHead>
                  <TableHead>Failed</TableHead>
                  <TableHead>الخطأ</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {logs.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={7} className="text-center text-muted-foreground">لا توجد سجلات</TableCell>
                  </TableRow>
                ) : (
                  logs.map((log) => (
                    <TableRow key={log.id}>
                      <TableCell>{toLocal(log.startedAt)}</TableCell>
                      <TableCell>{shortId(log.jobId)}</TableCell>
                      <TableCell>{log.jobType}</TableCell>
                      <TableCell>
                        <Badge variant={log.status === 'success' ? 'default' : log.status === 'failed' ? 'destructive' : 'secondary'}>
                          {log.status}
                        </Badge>
                      </TableCell>
                      <TableCell>{log.generatedDocuments}</TableCell>
                      <TableCell>{log.failedDocuments}</TableCell>
                      <TableCell className="max-w-[280px] truncate">{log.errorMessage || '-'}</TableCell>
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}
