import { useState, useEffect } from 'react';
import type { ReactElement } from 'react';
import { Layout } from '@/components/layout/Layout';
import {
  ViewAuditLogModal,
  DataTable,
  Pagination,
  FilterDropdown,
  StatusBadge,
  type Column,
} from '@/components/shared';
import { Download, ArrowUpDown } from 'lucide-react';
import { auditLogService } from '@/services/audit-log-service';
import type { AuditLog } from '@/types/audit-log';

// Helper function to format date
const formatDate = (dateString: string): string => {
  const date = new Date(dateString);
  return date.toLocaleDateString('en-US', {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
};

// Helper function to get action badge variant
const getActionVariant = (action: string): 'success' | 'failure' | 'info' | 'process' => {
  const lowerAction = action.toLowerCase();
  if (lowerAction.includes('create') || lowerAction.includes('register')) return 'success';
  if (lowerAction.includes('update') || lowerAction.includes('version_update') || lowerAction.includes('login')) return 'info';
  if (lowerAction.includes('delete') || lowerAction.includes('deregister')) return 'failure';
  if (lowerAction.includes('read') || lowerAction.includes('get') || lowerAction.includes('status_change')) return 'process';
  return 'info';
};

// Helper function to get method badge variant
const getMethodVariant = (method: string | null): 'success' | 'failure' | 'info' | 'process' => {
  if (!method) return 'info';
  const upperMethod = method.toUpperCase();
  if (upperMethod === 'GET') return 'success';
  if (upperMethod === 'POST') return 'info';
  if (upperMethod === 'PUT' || upperMethod === 'PATCH') return 'process';
  if (upperMethod === 'DELETE') return 'failure';
  return 'info';
};

// Helper function to get status badge color based on response status
const getStatusColor = (status: number | null): string => {
  if (!status) return 'text-[#6b7280]';
  if (status >= 200 && status < 300) return 'text-[#10b981]';
  if (status >= 300 && status < 400) return 'text-[#f59e0b]';
  if (status >= 400) return 'text-[#ef4444]';
  return 'text-[#6b7280]';
};

const AuditLogs = (): ReactElement => {
  const [auditLogs, setAuditLogs] = useState<AuditLog[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  // Pagination state
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [limit, setLimit] = useState<number>(5);
  const [pagination, setPagination] = useState<{
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasMore: boolean;
  }>({
    page: 1,
    limit: 5,
    total: 0,
    totalPages: 1,
    hasMore: false,
  });

  // Filter state
  const [methodFilter, setMethodFilter] = useState<string | null>(null);
  const [orderBy, setOrderBy] = useState<string[] | null>(null);

  // View modal
  const [viewModalOpen, setViewModalOpen] = useState<boolean>(false);
  const [selectedAuditLogId, setSelectedAuditLogId] = useState<string | null>(null);

  const fetchAuditLogs = async (
    page: number,
    itemsPerPage: number,
    method: string | null = null,
    sortBy: string[] | null = null
  ): Promise<void> => {
    try {
      setIsLoading(true);
      setError(null);
      const response = await auditLogService.getAll(page, itemsPerPage, method, sortBy);
      if (response.success) {
        setAuditLogs(response.data);
        setPagination(response.pagination);
      } else {
        setError('Failed to load audit logs');
      }
    } catch (err: any) {
      setError(err?.response?.data?.error?.message || 'Failed to load audit logs');
    } finally {
      setIsLoading(false);
    }
  };

  // Fetch audit logs on mount and when pagination/filters change
  useEffect(() => {
    fetchAuditLogs(currentPage, limit, methodFilter, orderBy);
  }, [currentPage, limit, methodFilter, orderBy]);

  // View audit log handler
  const handleViewAuditLog = (auditLogId: string): void => {
    setSelectedAuditLogId(auditLogId);
    setViewModalOpen(true);
  };

  // Load audit log for view
  const loadAuditLog = async (id: string): Promise<AuditLog> => {
    const response = await auditLogService.getById(id);
    return response.data;
  };

  // Define table columns
  const columns: Column<AuditLog>[] = [
    {
      key: 'created_at',
      label: 'Timestamp',
      render: (log) => (
        <span className="text-sm font-normal text-[#0f1724]">{formatDate(log.created_at)}</span>
      ),
      mobileLabel: 'Time',
    },
    {
      key: 'resource_type',
      label: 'Resource Type',
      render: (log) => (
        <span className="text-sm font-normal text-[#0f1724]">{log.resource_type}</span>
      ),
    },
    {
      key: 'action',
      label: 'Action',
      render: (log) => (
        <StatusBadge variant={getActionVariant(log.action)}>
          {log.action}
        </StatusBadge>
      ),
    },
    {
      key: 'resource_id',
      label: 'Resource ID',
      render: (log) => (
        <span className="text-sm font-normal text-[#0f1724] font-mono truncate max-w-[150px]">
          {log.resource_id || 'N/A'}
        </span>
      ),
    },
    {
      key: 'user',
      label: 'User',
      render: (log) => (
        <span className="text-sm font-normal text-[#0f1724]">
          {log.user ? `${log.user.first_name} ${log.user.last_name}` : 'N/A'}
        </span>
      ),
    },
    {
      key: 'request_method',
      label: 'Method',
      render: (log) => (
        <StatusBadge variant={getMethodVariant(log.request_method)}>
          {log.request_method ? log.request_method.toUpperCase() : 'N/A'}
        </StatusBadge>
      ),
    },
    {
      key: 'response_status',
      label: 'Status',
      render: (log) => (
        <span className={`text-sm font-normal ${getStatusColor(log.response_status)}`}>
          {log.response_status || 'N/A'}
        </span>
      ),
    },
    {
      key: 'ip_address',
      label: 'IP Address',
      render: (log) => (
        <span className="text-sm font-normal text-[#0f1724] font-mono">
          {log.ip_address || 'N/A'}
        </span>
      ),
    },
    {
      key: 'actions',
      label: 'Actions',
      align: 'right',
      render: (log) => (
        <div className="flex justify-end">
          <button
            type="button"
            onClick={() => handleViewAuditLog(log.id)}
            className="text-sm text-[#112868] hover:text-[#0d1f4e] font-medium transition-colors"
          >
            View
          </button>
        </div>
      ),
    },
  ];

  // Mobile card renderer
  const mobileCardRenderer = (log: AuditLog) => (
    <div className="p-4">
      <div className="flex items-start justify-between gap-3 mb-3">
        <div className="flex-1 min-w-0">
          <h3 className="text-sm font-medium text-[#0f1724] truncate">{log.resource_type}</h3>
          <div className="mt-1">
            <StatusBadge variant={getActionVariant(log.action)}>
              {log.action}
            </StatusBadge>
          </div>
        </div>
        <button
          type="button"
          onClick={() => handleViewAuditLog(log.id)}
          className="text-sm text-[#112868] hover:text-[#0d1f4e] font-medium transition-colors shrink-0"
        >
          View
        </button>
      </div>
      <div className="grid grid-cols-2 gap-3 text-xs">
        <div>
          <span className="text-[#9aa6b2]">Timestamp:</span>
          <p className="text-[#0f1724] font-normal mt-1">{formatDate(log.created_at)}</p>
        </div>
        <div>
          <span className="text-[#9aa6b2]">User:</span>
          <p className="text-[#0f1724] font-normal mt-1">
            {log.user ? `${log.user.first_name} ${log.user.last_name}` : 'N/A'}
          </p>
        </div>
        <div>
          <span className="text-[#9aa6b2]">Method:</span>
          <div className="mt-1">
            <StatusBadge variant={getMethodVariant(log.request_method)}>
              {log.request_method ? log.request_method.toUpperCase() : 'N/A'}
            </StatusBadge>
          </div>
        </div>
        <div>
          <span className="text-[#9aa6b2]">Status:</span>
          <p className={`font-normal mt-1 ${getStatusColor(log.response_status)}`}>
            {log.response_status || 'N/A'}
          </p>
        </div>
        <div>
          <span className="text-[#9aa6b2]">Resource ID:</span>
          <p className="text-[#0f1724] font-normal mt-1 font-mono truncate">
            {log.resource_id || 'N/A'}
          </p>
        </div>
        <div>
          <span className="text-[#9aa6b2]">IP Address:</span>
          <p className="text-[#0f1724] font-normal mt-1 font-mono">{log.ip_address || 'N/A'}</p>
        </div>
      </div>
    </div>
  );

  return (
    <Layout
      currentPage="Audit Logs"
      pageHeader={{
        title: 'Audit Logs',
        description: 'View and manage all audit logs in the QAssure platform.',
      }}
    >
      {/* Table Container */}
      <div className="bg-white border border-[rgba(0,0,0,0.08)] rounded-lg shadow-[0px_4px_24px_0px_rgba(0,0,0,0.02)] overflow-hidden">
        {/* Table Header with Filters */}
        <div className="border-b border-[rgba(0,0,0,0.08)] px-4 md:px-5 py-3 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3">
          {/* Filters */}
          <div className="flex flex-wrap items-center gap-3">
            {/* Method Filter */}
            <FilterDropdown
              label="Method"
              options={[
                { value: 'GET', label: 'GET' },
                { value: 'POST', label: 'POST' },
                { value: 'PUT', label: 'PUT' },
                { value: 'DELETE', label: 'DELETE' },
                { value: 'PATCH', label: 'PATCH' },
              ]}
              value={methodFilter}
              onChange={(value) => {
                setMethodFilter(value as string | null);
                setCurrentPage(1);
              }}
              placeholder="All"
            />

            {/* Sort Filter */}
            <FilterDropdown
              label="Sort by"
              options={[
                { value: ['created_at', 'desc'], label: 'Newest First' },
                { value: ['created_at', 'asc'], label: 'Oldest First' },
                { value: ['action', 'asc'], label: 'Action (A-Z)' },
                { value: ['action', 'desc'], label: 'Action (Z-A)' },
                { value: ['resource_type', 'asc'], label: 'Resource Type (A-Z)' },
                { value: ['resource_type', 'desc'], label: 'Resource Type (Z-A)' },
              ]}
              value={orderBy}
              onChange={(value) => {
                setOrderBy(value as string[] | null);
                setCurrentPage(1);
              }}
              placeholder="Default"
              showIcon
              icon={<ArrowUpDown className="w-3.5 h-3.5 text-[#475569]" />}
            />
          </div>

          {/* Actions */}
          <div className="flex items-center gap-2">
            {/* Export Button */}
            <button
              type="button"
              className="flex items-center gap-1.5 px-3 py-2 bg-white border border-[rgba(0,0,0,0.08)] rounded-md text-xs text-[#0f1724] hover:bg-gray-50 transition-colors cursor-pointer"
            >
              <Download className="w-3.5 h-3.5" />
              <span>Export</span>
            </button>
          </div>
        </div>

        {/* Table */}
        <DataTable
          columns={columns}
          data={auditLogs}
          keyExtractor={(log) => log.id}
          isLoading={isLoading}
          error={error}
          mobileCardRenderer={mobileCardRenderer}
          emptyMessage="No audit logs found"
        />

        {/* Pagination */}
        {pagination.total > 0 && (
          <div className="border-t border-[rgba(0,0,0,0.08)] px-4 md:px-5 py-3">
            <Pagination
              currentPage={pagination.page}
              totalPages={pagination.totalPages}
              totalItems={pagination.total}
              limit={limit}
              onPageChange={(page: number) => setCurrentPage(page)}
              onLimitChange={(newLimit: number) => {
                setLimit(newLimit);
                setCurrentPage(1);
              }}
            />
          </div>
        )}
      </div>

      {/* View Audit Log Modal */}
      <ViewAuditLogModal
        isOpen={viewModalOpen}
        onClose={() => {
          setViewModalOpen(false);
          setSelectedAuditLogId(null);
        }}
        auditLogId={selectedAuditLogId}
        onLoadAuditLog={loadAuditLog}
      />
    </Layout>
  );
};

export default AuditLogs;
