import React, { useState } from 'react';
import {
  FaHistory,
  FaSync,
  FaChevronDown,
  FaChevronUp,
  FaUser,
  FaClock,
  FaCheckCircle,
  FaSpinner,
} from 'react-icons/fa';
import { useAuditLogs } from '../hooks/useAuditLogs';
import type { AuditLogEntry, VersionChange } from '../hooks/useAuditLogs';

// ============== PROPS ==============

interface ActivityLogProps {
  /** Frappe DocType name (e.g. 'Asset', 'Inspection', 'Work_Order') */
  doctype: string;
  /** Document name / ID */
  docname: string | null;
  /** Document creation date (for "Created" entry at bottom) */
  creationDate?: string;
  /** Document owner/creator email */
  createdBy?: string;
  /** Title shown in header */
  title?: string;
  /** Max entries to fetch */
  limit?: number;
  /** Number of entries visible before "Show All" */
  initialVisible?: number;
  /** Allow collapse/expand */
  collapsible?: boolean;
  /** Start collapsed */
  startCollapsed?: boolean;
  /** Compact mode for sidebar placement */
  compact?: boolean;
  /** Additional CSS class */
  className?: string;
  /** Callback after refresh */
  onRefresh?: () => void;
}

// ============== HELPER FUNCTIONS ==============

const formatFieldName = (fieldName: string): string => {
  if (!fieldName) return '';
  return fieldName
    .replace(/^custom_/, '')
    .replace(/_/g, ' ')
    .replace(/\b\w/g, (char) => char.toUpperCase());
};

const formatValue = (value: any): string => {
  if (value === null || value === undefined) return '(empty)';
  if (value === '') return '(empty)';
  if (value === 0) return '0';
  if (value === 1) return '1';
  if (typeof value === 'boolean') return value ? 'Yes' : 'No';
  if (typeof value === 'object') return JSON.stringify(value);
  return String(value);
};

const formatAuditDate = (dateStr: string): string => {
  if (!dateStr) return '';
  const date = new Date(dateStr);
  const now = new Date();
  const diffMs = now.getTime() - date.getTime();
  const diffMins = Math.floor(diffMs / 60000);
  const diffHours = Math.floor(diffMs / 3600000);
  const diffDays = Math.floor(diffMs / 86400000);

  if (diffMins < 1) return 'Just now';
  if (diffMins < 60) return `${diffMins} min${diffMins > 1 ? 's' : ''} ago`;
  if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
  if (diffDays < 7) return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;

  return date.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: date.getFullYear() !== now.getFullYear() ? 'numeric' : undefined,
    hour: '2-digit',
    minute: '2-digit',
  });
};

const formatUsername = (email: string): string => {
  if (!email) return 'Unknown';
  const atIndex = email.indexOf('@');
  if (atIndex === -1) return email;
  return email.substring(0, atIndex);
};

const getChangeColor = (fieldName: string): string => {
  const lower = fieldName.toLowerCase();
  if (lower.includes('status') || lower.includes('state') || lower.includes('workflow')) {
    return 'text-purple-600 dark:text-purple-400';
  }
  if (lower.includes('date')) {
    return 'text-blue-600 dark:text-blue-400';
  }
  if (
    lower.includes('technician') ||
    lower.includes('supervisor') ||
    lower.includes('assigned') ||
    lower.includes('location') ||
    lower.includes('department') ||
    lower.includes('building') ||
    lower.includes('room')
  ) {
    return 'text-green-600 dark:text-green-400';
  }
  return 'text-gray-600 dark:text-gray-400';
};

// ============== SUB-COMPONENTS ==============

/** Single timeline entry */
const TimelineEntry: React.FC<{
  log: AuditLogEntry;
  isLatest: boolean;
  compact: boolean;
}> = ({ log, isLatest, compact }) => {
  const dotSize = compact ? 'w-2.5 h-2.5' : 'w-3 h-3';
  const avatarSize = compact ? 'w-5 h-5' : 'w-6 h-6';
  const iconSize = compact ? 8 : 10;
  const textSize = compact ? 'text-[10px]' : 'text-xs';
  const valueSize = compact ? 'text-[9px]' : 'text-[10px]';

  return (
    <div className={`relative ${compact ? 'pl-6' : 'pl-8'}`}>
      {/* Timeline dot */}
      <div
        className={`absolute ${compact ? 'left-1' : 'left-1.5'} top-1.5 ${dotSize} rounded-full border-2 border-white dark:border-gray-800 ${
          isLatest ? 'bg-blue-500' : 'bg-gray-300 dark:bg-gray-600'
        }`}
      />

      {/* Entry content */}
      <div
        className={`${compact ? 'p-2' : 'p-3'} rounded-lg ${
          isLatest
            ? 'bg-blue-50 dark:bg-blue-900/20 border border-blue-100 dark:border-blue-800/50'
            : 'bg-gray-50 dark:bg-gray-700/50'
        }`}
      >
        {/* Header */}
        <div className="flex items-center justify-between mb-1.5">
          <div className="flex items-center gap-1.5">
            <div
              className={`${avatarSize} rounded-full bg-gray-200 dark:bg-gray-600 flex items-center justify-center`}
            >
              <FaUser className="text-gray-500 dark:text-gray-400" size={iconSize} />
            </div>
            <span className={`${textSize} font-medium text-gray-700 dark:text-gray-300`}>
              {formatUsername(log.owner)}
            </span>
          </div>
          <div className={`flex items-center gap-1 ${textSize} text-gray-500 dark:text-gray-400`}>
            <FaClock size={iconSize} />
            <span title={new Date(log.creation).toLocaleString()}>
              {formatAuditDate(log.creation)}
            </span>
          </div>
        </div>

        {/* Changes */}
        <div className="space-y-1">
          {log.changes.length > 0 ? (
            log.changes.map((change, i) => (
              <div key={i} className={textSize}>
                <span className={`font-medium ${getChangeColor(change.field)}`}>
                  {formatFieldName(change.field)}
                </span>
                <span className="text-gray-500 dark:text-gray-400"> changed from </span>
                <span
                  className={`px-1 py-0.5 bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400 rounded ${valueSize} font-mono`}
                >
                  {formatValue(change.oldValue)}
                </span>
                <span className="text-gray-500 dark:text-gray-400"> → </span>
                <span
                  className={`px-1 py-0.5 bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400 rounded ${valueSize} font-mono`}
                >
                  {formatValue(change.newValue)}
                </span>
              </div>
            ))
          ) : (
            <p className={`${textSize} text-gray-500 dark:text-gray-400 italic`}>Document updated</p>
          )}

          {log.added && log.added.length > 0 && (
            <div className={`${textSize} text-green-600 dark:text-green-400`}>
              <span className="font-medium">Added:</span> {log.added.length} item(s)
            </div>
          )}
          {log.removed && log.removed.length > 0 && (
            <div className={`${textSize} text-red-600 dark:text-red-400`}>
              <span className="font-medium">Removed:</span> {log.removed.length} item(s)
            </div>
          )}
          {log.rowChanged && log.rowChanged.length > 0 && (
            <div className={`${textSize} text-orange-600 dark:text-orange-400`}>
              <span className="font-medium">Modified:</span> {log.rowChanged.length} row(s)
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

/** "Created this document" entry */
const CreatedEntry: React.FC<{
  creationDate: string;
  createdBy: string;
  doctype: string;
  compact: boolean;
}> = ({ creationDate, createdBy, doctype, compact }) => {
  const dotSize = compact ? 'w-2.5 h-2.5' : 'w-3 h-3';
  const avatarSize = compact ? 'w-5 h-5' : 'w-6 h-6';
  const iconSize = compact ? 8 : 10;
  const textSize = compact ? 'text-[10px]' : 'text-xs';

  // Clean doctype for display (e.g. "Work_Order" → "Work Order")
  const displayDoctype = doctype.replace(/_/g, ' ');

  return (
    <div className={`relative ${compact ? 'pl-6' : 'pl-8'}`}>
      <div
        className={`absolute ${compact ? 'left-1' : 'left-1.5'} top-1.5 ${dotSize} rounded-full border-2 border-white dark:border-gray-800 bg-green-500`}
      />
      <div
        className={`${compact ? 'p-2' : 'p-3'} rounded-lg bg-green-50 dark:bg-green-900/20 border border-green-100 dark:border-green-800/50`}
      >
        <div className="flex items-center justify-between mb-1">
          <div className="flex items-center gap-1.5">
            <div
              className={`${avatarSize} rounded-full bg-green-200 dark:bg-green-800 flex items-center justify-center`}
            >
              <FaUser className="text-green-600 dark:text-green-400" size={iconSize} />
            </div>
            <span className={`${textSize} font-medium text-gray-700 dark:text-gray-300`}>
              {formatUsername(createdBy)}
            </span>
          </div>
          <div className={`flex items-center gap-1 ${textSize} text-gray-500 dark:text-gray-400`}>
            <FaClock size={iconSize} />
            <span title={new Date(creationDate).toLocaleString()}>
              {formatAuditDate(creationDate)}
            </span>
          </div>
        </div>
        <span
          className={`inline-flex items-center gap-1 px-1.5 py-0.5 bg-green-100 dark:bg-green-800/50 text-green-700 dark:text-green-300 rounded ${textSize} font-medium`}
        >
          <FaCheckCircle size={iconSize} />
          Created this {displayDoctype}
        </span>
      </div>
    </div>
  );
};

// ============== MAIN COMPONENT ==============

const ActivityLog: React.FC<ActivityLogProps> = ({
  doctype,
  docname,
  creationDate,
  createdBy,
  title = 'Activity Log',
  limit = 50,
  initialVisible = 5,
  collapsible = true,
  startCollapsed = false,
  compact = false,
  className = '',
  onRefresh,
}) => {
  const [isExpanded, setIsExpanded] = useState(!startCollapsed);
  const [showAll, setShowAll] = useState(false);

  const { auditLogs, loading, refetch } = useAuditLogs({
    doctype,
    docname,
    limit,
    enabled: !!docname,
  });

  const handleRefresh = () => {
    refetch();
    onRefresh?.();
  };

  if (!docname) return null;

  const headerIconSize = compact ? 14 : 16;
  const headerTextClass = compact ? 'text-sm' : 'text-base';
  const timelineLineLeft = compact ? 'left-2' : 'left-3';
  const showMoreTextSize = compact ? 'text-[10px]' : 'text-xs';
  const showMoreIconSize = compact ? 8 : 10;

  const visibleLogs = showAll ? auditLogs : auditLogs.slice(0, initialVisible);

  return (
    <div
      className={`bg-white dark:bg-gray-800 rounded-xl shadow-md border border-gray-200 dark:border-gray-700 overflow-hidden ${className}`}
    >
      {/* Header */}
      <div className="flex items-center justify-between p-3 border-b border-gray-200 dark:border-gray-700">
        <div
          className={`flex items-center gap-2 flex-1 ${collapsible ? 'cursor-pointer' : ''}`}
          onClick={() => collapsible && setIsExpanded(!isExpanded)}
        >
          <FaHistory className="text-blue-500" size={headerIconSize} />
          <h2 className={`${headerTextClass} font-semibold text-gray-800 dark:text-white`}>
            {title}
          </h2>
          {auditLogs.length > 0 && (
            <span className="px-1.5 py-0.5 bg-blue-100 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400 rounded-full text-[10px] font-medium">
              {auditLogs.length}
            </span>
          )}
        </div>
        <div className="flex items-center gap-1">
          <button
            type="button"
            onClick={(e) => {
              e.stopPropagation();
              handleRefresh();
            }}
            disabled={loading}
            className="p-1 text-gray-400 hover:text-blue-500 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded transition-colors disabled:opacity-50"
            title="Refresh activity log"
          >
            <FaSync className={loading ? 'animate-spin' : ''} size={compact ? 10 : 12} />
          </button>
          {collapsible && (
            <button
              type="button"
              onClick={() => setIsExpanded(!isExpanded)}
              className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors p-1"
            >
              {isExpanded ? (
                <FaChevronUp size={compact ? 12 : 14} />
              ) : (
                <FaChevronDown size={compact ? 12 : 14} />
              )}
            </button>
          )}
        </div>
      </div>

      {/* Content */}
      {isExpanded && (
        <div className="p-3">
          {/* Loading */}
          {loading && (
            <div className="flex items-center justify-center py-6">
              <FaSpinner className="animate-spin text-blue-500 mr-2" size={14} />
              <span className="text-xs text-gray-500 dark:text-gray-400">Loading...</span>
            </div>
          )}

          {/* Empty State */}
          {!loading && auditLogs.length === 0 && (
            <div className="relative">
              <div className={`absolute ${timelineLineLeft} top-0 bottom-0 w-0.5 bg-gray-200 dark:bg-gray-700`} />

              <div className={`relative ${compact ? 'pl-6' : 'pl-8'} mb-3`}>
                <div
                  className={`absolute ${compact ? 'left-1' : 'left-1.5'} top-1 ${compact ? 'w-2.5 h-2.5' : 'w-3 h-3'} rounded-full border-2 border-white dark:border-gray-800 bg-gray-300 dark:bg-gray-600`}
                />
                <div className={`${compact ? 'p-2' : 'p-3'} rounded-lg bg-gray-50 dark:bg-gray-700/50`}>
                  <p className={`${compact ? 'text-[10px]' : 'text-xs'} text-gray-500 dark:text-gray-400 italic`}>
                    No changes recorded yet
                  </p>
                </div>
              </div>

              {creationDate && createdBy && (
                <CreatedEntry
                  creationDate={creationDate}
                  createdBy={createdBy}
                  doctype={doctype}
                  compact={compact}
                />
              )}
            </div>
          )}

          {/* Timeline */}
          {!loading && auditLogs.length > 0 && (
            <div className="relative">
              <div className={`absolute ${timelineLineLeft} top-0 bottom-0 w-0.5 bg-gray-200 dark:bg-gray-700`} />

              <div className="space-y-3">
                {visibleLogs.map((log, index) => (
                  <TimelineEntry
                    key={log.name}
                    log={log}
                    isLatest={index === 0}
                    compact={compact}
                  />
                ))}
              </div>

              {/* Show More/Less */}
              {auditLogs.length > initialVisible && (
                <div className="mt-3 text-center">
                  <button
                    type="button"
                    onClick={() => setShowAll(!showAll)}
                    className={`inline-flex items-center gap-1 px-2 py-1 ${showMoreTextSize} font-medium text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-md transition-colors`}
                  >
                    {showAll ? (
                      <>
                        <FaChevronUp size={showMoreIconSize} /> Show Less
                      </>
                    ) : (
                      <>
                        <FaChevronDown size={showMoreIconSize} /> Show All ({auditLogs.length})
                      </>
                    )}
                  </button>
                </div>
              )}

              {/* Created entry at bottom */}
              {creationDate && createdBy && (
                <div className="mt-3">
                  <CreatedEntry
                    creationDate={creationDate}
                    createdBy={createdBy}
                    doctype={doctype}
                    compact={compact}
                  />
                </div>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

export default ActivityLog;