'use client';

import React, { useRef, useState, useCallback } from 'react';
import toast from 'react-hot-toast';
import {
  FiFileText,
  FiDownload,
  FiTrash2,
  FiUploadCloud,
  FiImage,
  FiArchive,
  FiPaperclip,
} from 'react-icons/fi';
import {
  uploadEntryEvidence,
  deleteEntryEvidence,
  fetchEntryFileBlob,
} from '@/lib/api/previous-nc.api';
import type { NcSource } from './findings.types';

// ═══════════════════════════════════════════════════════════════════════
// Accepted file types (extensions and tiered size limits)
// ═══════════════════════════════════════════════════════════════════════

const STD_EXTS = [
  '.pdf',
  '.png',
  '.jpg',
  '.jpeg',
  '.webp',
  '.doc',
  '.docx',
  '.xls',
  '.xlsx',
];
const ARCHIVE_EXTS = ['.zip', '.rar', '.7z'];
const ALL_EXTS = [...STD_EXTS, ...ARCHIVE_EXTS];

const MAX_STD_SIZE = 20 * 1024 * 1024; // 20 MB
const MAX_ARCHIVE_SIZE = 50 * 1024 * 1024; // 50 MB

interface Props {
  source: NcSource;
  ncId: number;
  entryId: number;
  documentPath: string | null;
  onChange: (newPath: string | null) => void;
}

export default function EvidenceZone({
  source,
  ncId,
  entryId,
  documentPath,
  onChange,
}: Props) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0);
  const [dragOver, setDragOver] = useState(false);
  const [deleting, setDeleting] = useState(false);
  const [viewing, setViewing] = useState(false);

  const filename = documentPath ? extractFilename(documentPath) : null;
  const isLegacy = documentPath && !documentPath.startsWith('new:');
  const filetype = filename ? detectType(filename) : null;

  // ─── View ─────────────────────────────────────────────────────────
  const handleView = useCallback(async () => {
    if (!documentPath) return;
    setViewing(true);
    try {
      const blobUrl = await fetchEntryFileBlob(source, ncId, entryId);
      const win = window.open(blobUrl, '_blank');
      if (!win) toast.error('Popup blocked — allow popups for this site');
      setTimeout(() => URL.revokeObjectURL(blobUrl), 60_000);
    } catch (err: any) {
      toast.error(err?.message ?? 'Failed to open file');
    } finally {
      setViewing(false);
    }
  }, [source, ncId, entryId, documentPath]);

  // ─── Upload ───────────────────────────────────────────────────────
  const handleUpload = useCallback(
    async (file: File) => {
      const ext = ('.' + (file.name.split('.').pop() || '')).toLowerCase();
      if (!ALL_EXTS.includes(ext)) {
        toast.error(`Unsupported file type: ${ext}`);
        return;
      }
      const isArchive = ARCHIVE_EXTS.includes(ext);
      const maxSize = isArchive ? MAX_ARCHIVE_SIZE : MAX_STD_SIZE;
      const maxLabel = isArchive ? '50 MB' : '20 MB';
      if (file.size > maxSize) {
        toast.error(
          `File too large (${(file.size / 1024 / 1024).toFixed(1)} MB). Max ${maxLabel} for ${isArchive ? 'archives' : 'documents'}.`,
        );
        return;
      }
      setUploading(true);
      setProgress(0);
      try {
        const res = await uploadEntryEvidence(
          source,
          ncId,
          entryId,
          file,
          (pct) => setProgress(pct),
        );
        onChange(res.document_path);
        toast.success(`Uploaded: ${file.name}`);
      } catch (err: any) {
        toast.error(err?.message ?? 'Upload failed');
      } finally {
        setUploading(false);
        setProgress(0);
        if (inputRef.current) inputRef.current.value = '';
      }
    },
    [source, ncId, entryId, onChange],
  );

  // ─── Delete ────────────────────────────────────────────────────────
  const handleDelete = useCallback(async () => {
    if (!documentPath) return;
    const confirmed = window.confirm(
      isLegacy
        ? 'Remove this evidence file?\n\n(Legacy file — stays in the old CRM, only the link is cleared.)'
        : 'Delete this evidence file?\n\nThis cannot be undone.',
    );
    if (!confirmed) return;
    setDeleting(true);
    try {
      await deleteEntryEvidence(source, ncId, entryId);
      onChange(null);
      toast.success('Evidence removed');
    } catch (err: any) {
      toast.error(err?.message ?? 'Delete failed');
    } finally {
      setDeleting(false);
    }
  }, [source, ncId, entryId, documentPath, isLegacy, onChange]);

  // ─── Drag-drop ─────────────────────────────────────────────────────
  const onDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setDragOver(false);
      if (uploading) return;
      const file = e.dataTransfer.files?.[0];
      if (file) void handleUpload(file);
    },
    [uploading, handleUpload],
  );

  return (
    <div>
      {/* Section header */}
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          marginBottom: 10,
        }}
      >
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <FiPaperclip size={13} color="#64748b" />
          <span
            style={{
              fontSize: 10,
              fontWeight: 700,
              color: '#64748b',
              textTransform: 'uppercase',
              letterSpacing: '0.08em',
            }}
          >
            Evidence file
          </span>
        </div>
        <span
          style={{
            fontSize: 10,
            color: '#94a3b8',
            fontFamily: "'JetBrains Mono', monospace",
          }}
        >
          Max <span style={{ color: '#475569', fontWeight: 600 }}>20 MB</span>
          {' · '}
          <span style={{ color: '#15803d', fontWeight: 700 }}>50 MB archives</span>
        </span>
      </div>

      {/* Existing file row */}
      {documentPath && filename && (
        <div
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: 10,
            padding: '10px 12px',
            background: '#fff',
            border: '1px solid #e2e8f0',
            borderRadius: 8,
            marginBottom: 10,
          }}
        >
          <FileTypeIcon type={filetype} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div
              style={{
                fontSize: 12,
                fontWeight: 600,
                color: '#0b1220',
                overflow: 'hidden',
                textOverflow: 'ellipsis',
                whiteSpace: 'nowrap',
              }}
              title={filename}
            >
              {filename}
            </div>
            <div
              style={{
                fontSize: 10,
                color: '#94a3b8',
                marginTop: 2,
                display: 'flex',
                alignItems: 'center',
                gap: 6,
                fontFamily: "'JetBrains Mono', monospace",
              }}
            >
              <span
                style={{
                  padding: '1px 6px',
                  background: isLegacy ? '#f8fafc' : '#dcfce7',
                  color: isLegacy ? '#475569' : '#15803d',
                  borderRadius: 4,
                  fontWeight: 700,
                  fontSize: 9,
                  letterSpacing: '0.04em',
                }}
              >
                {isLegacy ? 'LEGACY' : 'NEW'}
              </span>
              <span>{filetype?.toUpperCase() || 'FILE'}</span>
            </div>
          </div>
          <button
            onClick={handleView}
            disabled={viewing}
            title="View / download"
            style={iconBtn(viewing)}
          >
            <FiDownload size={13} />
          </button>
          <button
            onClick={handleDelete}
            disabled={deleting}
            title={isLegacy ? 'Unlink (file stays in legacy)' : 'Delete file'}
            style={{
              ...iconBtn(deleting),
              color: '#dc2626',
              borderColor: '#fecaca',
            }}
          >
            <FiTrash2 size={13} />
          </button>
        </div>
      )}

      {/* Drop zone */}
      <label
        onDragEnter={(e) => {
          e.preventDefault();
          e.stopPropagation();
          if (!uploading) setDragOver(true);
        }}
        onDragOver={(e) => {
          e.preventDefault();
          e.stopPropagation();
          if (!uploading) setDragOver(true);
        }}
        onDragLeave={(e) => {
          e.preventDefault();
          e.stopPropagation();
          setDragOver(false);
        }}
        onDrop={onDrop}
        style={{
          display: 'block',
          padding: '20px 16px',
          border: `1.5px dashed ${dragOver ? '#185FA5' : '#cbd5e1'}`,
          borderRadius: 9,
          background: dragOver ? '#eff6ff' : uploading ? '#fafbfc' : '#fff',
          textAlign: 'center',
          cursor: uploading ? 'wait' : 'pointer',
          transition: 'all 0.15s',
        }}
      >
        <input
          ref={inputRef}
          type="file"
          accept={ALL_EXTS.join(',')}
          style={{ display: 'none' }}
          disabled={uploading}
          onChange={(e) => {
            const file = e.target.files?.[0];
            if (file) void handleUpload(file);
          }}
        />

        {uploading ? (
          <UploadProgress percent={progress} />
        ) : (
          <>
            <div
              style={{
                display: 'inline-flex',
                alignItems: 'center',
                justifyContent: 'center',
                width: 38,
                height: 38,
                background: dragOver ? '#dbeafe' : '#f1f5f9',
                border: '1px solid',
                borderColor: dragOver ? '#bfdbfe' : '#e2e8f0',
                borderRadius: 50,
                marginBottom: 8,
              }}
            >
              <FiUploadCloud
                size={18}
                color={dragOver ? '#185FA5' : '#64748b'}
              />
            </div>
            <div
              style={{
                fontSize: 12,
                color: dragOver ? '#185FA5' : '#1f2937',
                fontWeight: 500,
              }}
            >
              {documentPath
                ? 'Drop new file to replace, or '
                : 'Drag a file here, or '}
              <span
                style={{
                  color: '#185FA5',
                  textDecoration: 'underline',
                  fontWeight: 600,
                }}
              >
                click to browse
              </span>
            </div>
            <div
              style={{
                marginTop: 9,
                display: 'inline-flex',
                gap: 6,
                flexWrap: 'wrap',
                justifyContent: 'center',
                alignItems: 'center',
              }}
            >
              <FormatChip icon={<FiFileText size={10} />} label="PDF" />
              <FormatChip icon={<FiImage size={10} />} label="JPG · PNG" />
              <FormatChip icon={<FiFileText size={10} />} label="DOC · DOCX" />
              <FormatChip icon={<FiFileText size={10} />} label="XLS · XLSX" />
              <FormatChip
                icon={<FiArchive size={10} />}
                label="ZIP · RAR · 7Z"
                highlight
              />
            </div>
          </>
        )}
      </label>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════════════
// Sub-components
// ═══════════════════════════════════════════════════════════════════════

function UploadProgress({ percent }: { percent: number }) {
  return (
    <div>
      <div
        style={{
          fontSize: 12,
          fontWeight: 600,
          color: '#185FA5',
          marginBottom: 6,
        }}
      >
        Uploading… {percent}%
      </div>
      <div
        style={{
          width: '70%',
          maxWidth: 280,
          margin: '0 auto',
          height: 6,
          background: '#e2e8f0',
          borderRadius: 3,
          overflow: 'hidden',
        }}
      >
        <div
          style={{
            width: `${percent}%`,
            height: '100%',
            background: '#185FA5',
            transition: 'width 0.2s',
          }}
        />
      </div>
    </div>
  );
}

function FormatChip({
  icon,
  label,
  highlight,
}: {
  icon: React.ReactNode;
  label: string;
  highlight?: boolean;
}) {
  return (
    <span
      style={{
        fontSize: 9,
        padding: '3px 8px',
        background: highlight ? '#ecfdf5' : '#fff',
        border: highlight ? '1px solid #a7f3d0' : '1px solid #e2e8f0',
        borderRadius: 99,
        color: highlight ? '#15803d' : '#475569',
        fontWeight: highlight ? 700 : 600,
        display: 'inline-flex',
        alignItems: 'center',
        gap: 4,
        letterSpacing: '0.02em',
      }}
    >
      {icon}
      {label}
    </span>
  );
}

function FileTypeIcon({ type }: { type: string | null }) {
  const isArchive =
    type === 'zip' || type === 'rar' || type === '7z';
  const isImage =
    type === 'jpg' || type === 'jpeg' || type === 'png' || type === 'webp';
  const color = isArchive ? '#15803d' : isImage ? '#854F0B' : '#185FA5';
  const bg = isArchive ? '#ecfdf5' : isImage ? '#FAEEDA' : '#E6F1FB';
  const Icon = isArchive ? FiArchive : isImage ? FiImage : FiFileText;
  return (
    <div
      style={{
        display: 'inline-flex',
        alignItems: 'center',
        justifyContent: 'center',
        width: 32,
        height: 32,
        background: bg,
        borderRadius: 6,
        flexShrink: 0,
      }}
    >
      <Icon size={16} color={color} />
    </div>
  );
}

function iconBtn(disabled = false): React.CSSProperties {
  return {
    background: '#fff',
    border: '1px solid #e2e8f0',
    borderRadius: 6,
    padding: '6px 8px',
    cursor: disabled ? 'wait' : 'pointer',
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    color: '#475569',
    transition: 'all 0.12s',
    opacity: disabled ? 0.5 : 1,
  };
}

// ═══════════════════════════════════════════════════════════════════════
// Helpers
// ═══════════════════════════════════════════════════════════════════════

function extractFilename(dbPath: string): string {
  const p = dbPath.startsWith('new:') ? dbPath.slice(4) : dbPath;
  const parts = p.split('/');
  return parts[parts.length - 1] || dbPath;
}

function detectType(filename: string): string {
  const ext = (filename.split('.').pop() || '').toLowerCase();
  return ext;
}