'use client';

import React, { useRef, useState } from 'react';
import {
  FiUploadCloud,
  FiFile,
  FiCheckCircle,
  FiExternalLink,
  FiX,
  FiAlertCircle,
} from 'react-icons/fi';
import type { MyAuditRow } from '@/lib/api/types/my-audits.types';
import { uploadAuditDocument, fetchAuditDocumentBlob } from '@/lib/api/audit-documents.api';
type DocKey =
  | 'stage1_report'
  | 'stage2_report'
  | 'attendance'
  | 'nc_form'
  | 'support_docs';

interface DocSlot {
  key: DocKey;
  label: string;
  hint: string;
  accept: string;
  accent: string; // header accent color
}

const DOC_SLOTS: DocSlot[] = [
  { key: 'stage1_report', label: 'Stage 1 Report', hint: 'PDF or Word', accept: '.pdf,.doc,.docx', accent: '#2563eb' },
  { key: 'stage2_report', label: 'Stage 2 Report', hint: 'PDF or Word', accept: '.pdf,.doc,.docx', accent: '#7c3aed' },
  { key: 'attendance', label: 'Attendance Sheet', hint: 'PDF or image', accept: '.pdf,.jpg,.jpeg,.png', accent: '#0891b2' },
  { key: 'nc_form', label: 'NC Form', hint: 'PDF or Word', accept: '.pdf,.doc,.docx', accent: '#ea580c' },
  { key: 'support_docs', label: 'Supporting Documents', hint: 'PDF, Word, image, zip', accept: '.pdf,.doc,.docx,.jpg,.jpeg,.png,.zip', accent: '#16a34a' },
];

function prettySize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB`;
  return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
}

// 🔌 XHR upload with progress. Wire the URL to your real endpoint.
function uploadWithProgress(
  rowId: number,
  docType: DocKey,
  file: File,
  onProgress: (pct: number) => void,
): Promise<{ path: string }> {
  return new Promise((resolve, reject) => {
    const form = new FormData();
    form.append('file', file);
    form.append('doc_type', docType);

    const xhr = new XMLHttpRequest();
    xhr.open('POST', `/api/audits/${rowId}/documents`, true);
    xhr.withCredentials = true;

    xhr.upload.onprogress = (e) => {
      if (e.lengthComputable) onProgress(Math.round((e.loaded / e.total) * 100));
    };
    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        try {
          resolve(JSON.parse(xhr.responseText));
        } catch {
          resolve({ path: '' });
        }
      } else {
        reject(new Error(xhr.responseText || `Upload failed (${xhr.status})`));
      }
    };
    xhr.onerror = () => reject(new Error('Network error during upload'));
    xhr.send(form);
  });
}

function existingPathFor(row: MyAuditRow, key: DocKey): string | null {
  const r = row as any;
  const map: Record<DocKey, string | null | undefined> = {
    stage1_report: r.stg1_audit_report ?? r.stage1_report,
    stage2_report: r.stg2_audit_report ?? r.stage2_report,
    attendance: r.attendance_doc,
    nc_form: r.nc_form_doc,
    support_docs: r.support_docs,
  };
  const v = map[key];
  return v ? String(v) : null;
}

type Phase = 'idle' | 'selected' | 'uploading' | 'done' | 'error';

interface SlotState {
  file: File | null;
  phase: Phase;
  progress: number;
  uploadedPath: string | null;
  error: string | null;
}

function DocCard({
  slot,
  rowId,
  initialPath,
}: {
  slot: DocSlot;
  rowId: number;
  initialPath: string | null;
}) {
  const [s, setS] = useState<SlotState>({
    file: null,
    phase: initialPath ? 'done' : 'idle',
    progress: 0,
    uploadedPath: initialPath,
    error: null,
  });
  const [dragOver, setDragOver] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  const pick = (file: File | null) => {
    if (!file) return;
    setS((p) => ({ ...p, file, phase: 'selected', error: null, progress: 0 }));
  };

  const start = async () => {
    if (!s.file) return;
    setS((p) => ({ ...p, phase: 'uploading', progress: 0, error: null }));
    try {
      const res = await uploadAuditDocument(rowId, slot.key, s.file, (pct) =>
        setS((p) => ({ ...p, progress: pct })),
      );
      setS((p) => ({
        ...p,
        phase: 'done',
        uploadedPath: res.document_path || p.uploadedPath,
        progress: 100,
      }));
    } catch (e: any) {
      setS((p) => ({ ...p, phase: 'error', error: e?.message || 'Upload failed' }));
    }
  };

  // 🆕 open the stored file (it's a "new:" path, not a public URL)
  const view = async () => {
    try {
      const blobUrl = await fetchAuditDocumentBlob(rowId, slot.key);
      window.open(blobUrl, '_blank');
    } catch (e: any) {
      setS((p) => ({ ...p, error: e?.message || 'Could not open file' }));
    }
  };

  const reset = () =>
    setS((p) => ({ ...p, file: null, phase: p.uploadedPath ? 'done' : 'idle', progress: 0, error: null }));

  return (
    <div
      style={{
        background: '#fff',
        border: '1px solid #e5e7eb',
        borderRadius: 14,
        overflow: 'hidden',
        boxShadow: '0 1px 3px rgba(0,0,0,0.04)',
      }}
    >
      {/* header */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '14px 16px', borderBottom: '1px solid #f3f4f6' }}>
        <div
          style={{
            width: 36, height: 36, borderRadius: 9, flexShrink: 0,
            background: `${slot.accent}14`, color: slot.accent,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}
        >
          <FiFile size={18} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: '#111827' }}>{slot.label}</div>
          <div style={{ fontSize: 11, color: '#9ca3af' }}>{slot.hint}</div>
        </div>
        {s.phase === 'done' && (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 11, fontWeight: 600, color: '#16a34a', background: '#f0fdf4', padding: '4px 9px', borderRadius: 999 }}>
            <FiCheckCircle size={12} /> Uploaded
          </span>
        )}
      </div>

      {/* body */}
      <div style={{ padding: 16 }}>
        {/* drop zone — shown when idle / done-with-no-pending-file */}
        {(s.phase === 'idle' || (s.phase === 'done' && !s.file)) && (
          <div
            onClick={() => inputRef.current?.click()}
            onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
            onDragLeave={() => setDragOver(false)}
            onDrop={(e) => { e.preventDefault(); setDragOver(false); pick(e.dataTransfer.files?.[0] ?? null); }}
            style={{
              border: `2px dashed ${dragOver ? slot.accent : '#d1d5db'}`,
              background: dragOver ? `${slot.accent}08` : '#fafafa',
              borderRadius: 10, padding: '22px 16px', textAlign: 'center', cursor: 'pointer',
              transition: 'all .15s',
            }}
          >
            <FiUploadCloud size={26} color={dragOver ? slot.accent : '#9ca3af'} />
            <div style={{ marginTop: 8, fontSize: 13, color: '#374151', fontWeight: 600 }}>
              {s.phase === 'done' ? 'Replace file' : 'Drop file or click to browse'}
            </div>
            <div style={{ marginTop: 2, fontSize: 11, color: '#9ca3af' }}>Max 50 MB</div>
          </div>
        )}

        {/* selected — ready to upload */}
        {s.phase === 'selected' && s.file && (
          <div>
            <FileRow name={s.file.name} size={s.file.size} onClear={reset} />
            <button type="button" onClick={start} style={primaryBtn(slot.accent)}>
              <FiUploadCloud size={15} /> <span>Upload</span>
            </button>
          </div>
        )}

        {/* uploading — progress */}
        {s.phase === 'uploading' && s.file && (
          <div>
            <FileRow name={s.file.name} size={s.file.size} />
            <div style={{ marginTop: 10, height: 8, borderRadius: 999, background: '#f3f4f6', overflow: 'hidden' }}>
              <div style={{ width: `${s.progress}%`, height: '100%', background: slot.accent, borderRadius: 999, transition: 'width .15s' }} />
            </div>
            <div style={{ marginTop: 6, fontSize: 12, color: '#6b7280', textAlign: 'right' }}>{s.progress}%</div>
          </div>
        )}

        {/* error */}
        {s.phase === 'error' && (
          <div>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, background: '#fef2f2', border: '1px solid #fecaca', borderRadius: 9, padding: '10px 12px' }}>
              <FiAlertCircle size={16} color="#dc2626" style={{ marginTop: 1, flexShrink: 0 }} />
              <div style={{ fontSize: 12, color: '#991b1b' }}>{s.error}</div>
            </div>
            <button type="button" onClick={start} style={primaryBtn(slot.accent)}>
              <FiUploadCloud size={15} /> <span>Retry</span>
            </button>
          </div>
        )}

        {/* done — view link */}
        {s.phase === 'done' && s.uploadedPath && !s.file && (
          <button
            type="button"
            onClick={view}
            style={{
              marginTop: 12, width: '100%', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
              border: '1px solid #e5e7eb', background: '#fff', borderRadius: 9, padding: '9px 14px',
              fontSize: 13, fontWeight: 600, color: '#374151', cursor: 'pointer',
            }}
          >
            <FiExternalLink size={14} /> <span>View uploaded file</span>
          </button>
        )}

        <input
          ref={inputRef}
          type="file"
          accept={slot.accept}
          style={{ display: 'none' }}
          onChange={(e) => pick(e.target.files?.[0] ?? null)}
        />
      </div>
    </div>
  );
}

function FileRow({ name, size, onClear }: { name: string; size: number; onClear?: () => void }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10, background: '#f9fafb', border: '1px solid #f3f4f6', borderRadius: 9, padding: '10px 12px' }}>
      <FiFile size={16} color="#6b7280" style={{ flexShrink: 0 }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, color: '#111827', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{name}</div>
        <div style={{ fontSize: 11, color: '#9ca3af' }}>{prettySize(size)}</div>
      </div>
      {onClear && (
        <button type="button" onClick={onClear} style={{ border: 'none', background: 'transparent', cursor: 'pointer', color: '#9ca3af', padding: 4 }}>
          <FiX size={16} />
        </button>
      )}
    </div>
  );
}

function primaryBtn(accent: string): React.CSSProperties {
  return {
    marginTop: 12, width: '100%', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 6,
    border: 'none', borderRadius: 9, padding: '10px 14px',
    fontSize: 13, fontWeight: 700, color: '#fff', cursor: 'pointer', background: accent,
  };
}

export default function DocumentsTab({ row }: { row: MyAuditRow }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div>
        <h2 style={{ margin: 0, fontSize: 16, fontWeight: 700, color: '#111827' }}>Audit Documents</h2>
        <p style={{ margin: '4px 0 0', fontSize: 13, color: '#6b7280' }}>
          Upload reports and evidence for <strong>{row.audit_code}</strong>.
        </p>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 14 }}>
        {DOC_SLOTS.map((slot) => (
          <DocCard
            key={slot.key}
            slot={slot}
            rowId={row.id}
            initialPath={existingPathFor(row, slot.key)}
          />
        ))}
      </div>
    </div>
  );
}