import { useMemo, useState } from 'react';
import { Button } from '@/components/ui/button';

// ============================================================
// التحقق الذكي من الملف: هل هو كشف بنكي حقيقي؟
// ============================================================

type ValidationLevel = 'ok' | 'warning' | 'error';

interface ValidationResult {
  level: ValidationLevel;
  issues: string[];
  score: number; // 0-100
}

function validateBankStatement(
  mapping: Record<string, string>,
  previewRows: string[][]
): ValidationResult {
  const issues: string[] = [];
  let score = 100;

  const mappedFields = Object.values(mapping).filter(Boolean);
  const hasDate = mappedFields.includes('transactionDate');
  const hasAmount = mappedFields.includes('amount');
  const hasDebit = mappedFields.includes('debit');
  const hasCredit = mappedFields.includes('credit');
  const hasAnyAmount = hasAmount || hasDebit || hasCredit;

  // ---- حقول أساسية ----
  if (!hasDate) {
    issues.push('لم يتم ربط عمود التاريخ — التاريخ ضروري للتسوية البنكية.');
    score -= 40;
  }
  if (!hasAnyAmount) {
    issues.push('لم يتم ربط أي عمود للمبلغ (مدين / دائن / مبلغ) — المبلغ ضروري.');
    score -= 40;
  }
  if (hasDebit && !hasCredit) {
    issues.push('تم ربط "مدين" فقط دون "دائن" — قد تكون البيانات ناقصة.');
    score -= 10;
  }
  if (!hasDebit && hasCredit) {
    issues.push('تم ربط "دائن" فقط دون "مدين" — قد تكون البيانات ناقصة.');
    score -= 10;
  }

  // ---- التحقق من البيانات الفعلية ----
  if (previewRows.length === 0) {
    issues.push('الملف لا يحتوي على صفوف بيانات.');
    score -= 30;
  } else {
    // دالة مساعدة: هل القيمة تبدو كتاريخ حقيقي؟
    const isLikelyDate = (v: string): boolean => {
      const str = String(v).trim();
      if (!str) return false;
      // تنسيق بفواصل: DD/MM/YYYY أو YYYY-MM-DD إلخ (يجب أن يحتوي على فاصل)
      if (/^\d{1,4}[\/\-\.]\d{1,2}[\/\-\.]\d{2,4}$/.test(str)) return true;
      // تنسيق ISO كامل
      if (/^\d{4}-\d{2}-\d{2}(T.*)?$/.test(str)) return true;
      // رقم تسلسلي Excel (تواريخ 1900–2100 = 1 إلى ~73050، لكن نتجنب أرقام الأصناف < 30000)
      const num = Number(str);
      if (Number.isFinite(num) && num > 30000 && num < 73050) return true;
      // أسماء الأشهر بالإنجليزية
      if (/\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\b/i.test(str)) return true;
      return false;
    };

    // التحقق من عمود التاريخ: هل تبدو القيم كتواريخ؟
    const dateCol = Object.entries(mapping).find(([, v]) => v === 'transactionDate')?.[0];
    const colHeaders = Object.keys(mapping);
    const dateColIdx = dateCol ? colHeaders.indexOf(dateCol) : -1;
    if (dateColIdx >= 0) {
      const dateValues = previewRows.slice(0, 5).map((r) => r[dateColIdx]).filter(Boolean);
      const validDates = dateValues.filter((v) => isLikelyDate(v));
      if (dateValues.length > 0 && validDates.length / dateValues.length < 0.5) {
        issues.push(
          `عمود التاريخ المختار (القيم مثل: "${dateValues.slice(0, 2).join('، ')}") لا يبدو أنه يحتوي على تواريخ صحيحة.`
        );
        score -= 35;
      }
    }

    // التحقق من عمود المبلغ: هل القيم أرقام؟
    const amountCol = Object.entries(mapping).find(([, v]) => v === 'amount' || v === 'debit' || v === 'credit')?.[0];
    const amountColIdx = amountCol ? colHeaders.indexOf(amountCol) : -1;
    if (amountColIdx >= 0) {
      const amtValues = previewRows.slice(0, 5).map((r) => r[amountColIdx]).filter((v) => v !== '' && v !== null && v !== undefined);
      const validAmounts = amtValues.filter((v) => {
        const n = Number(String(v).replace(/,/g, '').replace(/\s/g, ''));
        return Number.isFinite(n);
      });
      if (amtValues.length > 0 && validAmounts.length / amtValues.length < 0.5) {
        issues.push(
          `عمود المبلغ المختار (القيم مثل: "${amtValues.slice(0, 2).join('، ')}") لا يحتوي على أرقام صحيحة.`
        );
        score -= 25;
      }
    }

    // التحقق: عدد الأعمدة المربوطة مقارنة بالإجمالي
    const nonIgnored = mappedFields.length;
    const total = Object.keys(mapping).length;
    if (total >= 3 && nonIgnored === 0) {
      issues.push('لم يتم ربط أي عمود — يبدو أن الملف ليس كشف بنكي.');
      score -= 30;
    }
  }

  score = Math.max(0, score);
  const level: ValidationLevel = score >= 70 ? 'ok' : score >= 40 ? 'warning' : 'error';
  return { level, issues, score };
}

const DEFAULT_FIELD_OPTIONS = [
  { value: '', label: '— تجاهل —' },
  { value: 'transactionDate', label: 'التاريخ' },
  { value: 'amount', label: 'المبلغ' },
  { value: 'debit', label: 'مدين' },
  { value: 'credit', label: 'دائن' },
  { value: 'direction', label: 'الاتجاه (وارد/صادر)' },
  { value: 'description', label: 'الوصف' },
  { value: 'bankReference', label: 'المرجع البنكي' },
  { value: 'type', label: 'نوع الحركة' },
  { value: 'currencyCode', label: 'العملة' },
];

export function BankStatementColumnMapper({
  headers,
  previewRows,
  onConfirm,
  loading,
}: {
  headers: string[];
  previewRows: string[][];
  onConfirm: (mapping: Record<string, string>) => void;
  loading?: boolean;
}) {
  const [mapping, setMapping] = useState<Record<string, string>>(() => {
    // Guess initial mapping by header name
    const guess: Record<string, string> = {};
    headers.forEach((h) => {
      const norm = h.trim().toLowerCase();
      if (norm.includes('date') || norm.includes('تاريخ')) guess[h] = 'transactionDate';
      else if (norm.includes('amount') || norm.includes('مبلغ')) guess[h] = 'amount';
      else if (norm.includes('debit') || norm.includes('مدين')) guess[h] = 'debit';
      else if (norm.includes('credit') || norm.includes('دائن')) guess[h] = 'credit';
      else if (norm.includes('direction') || norm.includes('اتجاه')) guess[h] = 'direction';
      else if (norm.includes('desc') || norm.includes('وصف') || norm.includes('بيان')) guess[h] = 'description';
      else if (norm.includes('ref') || norm.includes('مرجع')) guess[h] = 'bankReference';
      else if (norm.includes('type') || norm.includes('نوع')) guess[h] = 'type';
      else if (norm.includes('curr') || norm.includes('عملة')) guess[h] = 'currencyCode';
      else guess[h] = '';
    });
    return guess;
  });
  const [fieldOptions, setFieldOptions] = useState(DEFAULT_FIELD_OPTIONS);
  const [showAddField, setShowAddField] = useState(false);
  const [newFieldName, setNewFieldName] = useState('');
  const [forceConfirm, setForceConfirm] = useState(false);

  const handleChange = (col: string, value: string) => {
    setForceConfirm(false);
    setMapping((prev) => ({ ...prev, [col]: value }));
  };

  const handleAddField = () => {
    const clean = newFieldName.trim();
    if (!clean) return;
    if (fieldOptions.some((f) => f.value === clean)) return;
    setFieldOptions((prev) => [...prev, { value: clean, label: clean }]);
    setNewFieldName('');
    setShowAddField(false);
  };

  const validation = useMemo(() => validateBankStatement(mapping, previewRows), [mapping, previewRows]);

  const canConfirm = validation.level !== 'error' || forceConfirm;

  return (
    <div className="space-y-4">
      <div className="flex items-center gap-2 mb-2">
        <Button type="button" size="sm" variant="outline" onClick={() => setShowAddField((v) => !v)}>
          إضافة حقل مخصص
        </Button>
        {showAddField && (
          <form
            onSubmit={(e) => {
              e.preventDefault();
              handleAddField();
            }}
            className="flex items-center gap-2"
          >
            <input
              className="border rounded px-2 py-1 text-xs"
              placeholder="اسم الحقل الجديد"
              value={newFieldName}
              onChange={(e) => setNewFieldName(e.target.value)}
              autoFocus
            />
            <Button type="submit" size="sm">إضافة</Button>
          </form>
        )}
      </div>
      <div className="overflow-auto rounded border">
        <table className="min-w-full text-xs">
          <thead>
            <tr>
              {headers.map((col, idx) => (
                <th key={col + idx} className="p-2 border-b bg-muted">
                  <select
                    className="rounded border px-1 py-0.5 text-xs"
                    value={mapping[col] || ''}
                    onChange={(e) => handleChange(col, e.target.value)}
                  >
                    {fieldOptions.map((opt) => (
                      <option key={opt.value} value={opt.value}>{opt.label}</option>
                    ))}
                  </select>
                  <div className="mt-1 text-[11px] text-muted-foreground">{col}</div>
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {previewRows.map((row, i) => (
              <tr key={i} className="border-b">
                {row.map((cell, j) => (
                  <td key={j} className="p-1 text-center max-w-[120px] truncate">{cell}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      {/* ===== نتيجة التحقق الذكي ===== */}
      {validation.issues.length > 0 && (
        <div
          className={`rounded-md border px-4 py-3 text-sm space-y-1 ${
            validation.level === 'error'
              ? 'border-red-300 bg-red-50 text-red-800'
              : 'border-amber-300 bg-amber-50 text-amber-800'
          }`}
        >
          <p className="font-semibold flex items-center gap-1">
            {validation.level === 'error' ? '✗' : '⚠'}{' '}
            {validation.level === 'error'
              ? 'هذا الملف لا يبدو أنه كشف بنكي صحيح'
              : 'تحذير: الملف قد لا يكون كشفاً بنكياً كاملاً'}
            <span className="ml-auto text-xs font-normal opacity-60">نسبة الثقة: {validation.score}%</span>
          </p>
          <ul className="list-disc list-inside space-y-0.5 text-xs">
            {validation.issues.map((issue, i) => (
              <li key={i}>{issue}</li>
            ))}
          </ul>
          {validation.level === 'error' && !forceConfirm && (
            <button
              type="button"
              className="mt-1 text-xs underline text-red-700 hover:text-red-900"
              onClick={() => setForceConfirm(true)}
            >
              أعلم بذلك — أرغب بالمتابعة رغم ذلك
            </button>
          )}
        </div>
      )}

      {validation.level === 'ok' && validation.issues.length === 0 && (
        <div className="rounded-md border border-green-300 bg-green-50 px-4 py-2 text-sm text-green-800 flex items-center gap-2">
          <span>✓</span>
          <span>يبدو أن الملف كشف بنكي صحيح — جاهز للاستيراد (نسبة الثقة: {validation.score}%)</span>
        </div>
      )}

      <div className="flex justify-end">
        <Button
          onClick={() => onConfirm(mapping)}
          disabled={loading || !canConfirm}
          variant={validation.level === 'warning' ? 'outline' : 'default'}
          className={
            validation.level === 'ok'
              ? 'bg-green-600 hover:bg-green-700 text-white'
              : validation.level === 'warning'
              ? 'border-amber-500 text-amber-700 hover:bg-amber-50'
              : ''
          }
        >
          {loading
            ? 'جاري الاستيراد...'
            : validation.level === 'ok'
            ? '✓ تأكيد الربط والاستيراد'
            : validation.level === 'warning'
            ? '⚠ استيراد رغم التحذير'
            : '✗ يتعذر الاستيراد — يرجى مراجعة الربط'}
        </Button>
      </div>
    </div>
  );
}
