import { useState, useMemo, useEffect, useCallback, CSSProperties } from 'react';
import { Card, Table, Button, Select, Row, Col, Typography, DatePicker, message, Tag } from 'antd';
import { ArrowLeftOutlined, DownloadOutlined, SearchOutlined } from '@ant-design/icons';
import { request } from '../api/client';
import { useNavigate } from 'react-router-dom';
import type { TableColumnsType, TablePaginationConfig } from 'antd';
import type { Dayjs } from 'dayjs';

interface AuditLog {
  id: string;
  user_id: string | null;
  action_type: string;
  entity_type: string | null;
  entity_id: string | null;
  timestamp: string;
  ip_address: string | null;
  details: Record<string, unknown> | null;
  created_at: string;
  updated_at: string;
}

interface User {
  id: string;
  email: string;
  first_name: string;
  last_name: string;
}

export default function AuditLogsPage() {
  const [messageApi, contextHolder] = message.useMessage();
  const navigate = useNavigate();

  const [auditLogs, setAuditLogs] = useState<AuditLog[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [filterDateRange, setFilterDateRange] = useState<[Dayjs | null, Dayjs | null] | null>(null);
  const [filterUserId, setFilterUserId] = useState<string>('');
  const [filterActionType, setFilterActionType] = useState<string>('');
  const [filterEntityType, setFilterEntityType] = useState<string>('');
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [totalRecords, setTotalRecords] = useState<number>(0);
  const [users, setUsers] = useState<User[]>([]);

  const paginationOffset = useMemo(() => {
    return (currentPage - 1) * 50;
  }, [currentPage]);

  const fetchAuditLogs = useCallback(async () => {
    setLoading(true);
    try {
      const queryParams: Record<string, string | number> = {
        limit: 50,
        offset: paginationOffset,
      };
      if (filterUserId) {
        queryParams.user_id = filterUserId;
      }
      if (filterActionType) {
        queryParams.action_type = filterActionType;
      }
      if (filterEntityType) {
        queryParams.entity_type = filterEntityType;
      }

      const result = await request<AuditLog[]>({
        method: 'GET',
        path: '/system/audit-logs',
        query: queryParams,
      });

      setAuditLogs(result.data);
      setTotalRecords(result.data.length);
    } catch (error) {
      messageApi.error('Failed to load audit logs');
    } finally {
      setLoading(false);
    }
  }, [paginationOffset, filterUserId, filterActionType, filterEntityType, messageApi]);

  const fetchUsers = useCallback(async () => {
    try {
      const result = await request<User[]>({
        method: 'GET',
        path: '/auth/users',
        query: {
          limit: 100,
          offset: 0,
        },
      });
      setUsers(result.data);
    } catch (error) {
      messageApi.error('Failed to load users');
    }
  }, [messageApi]);

  useEffect(() => {
    fetchAuditLogs();
  }, [fetchAuditLogs]);

  useEffect(() => {
    fetchUsers();
  }, [fetchUsers]);

  const searchAuditLogs = useCallback(() => {
    setCurrentPage(1);
    fetchAuditLogs();
  }, [fetchAuditLogs]);

  const exportCsv = useCallback(() => {
    try {
      const headers = ['Timestamp', 'User ID', 'Action Type', 'Entity Type', 'Entity ID', 'IP Address', 'Details'];
      const csvRows = [headers.join(',')];

      auditLogs.forEach((log) => {
        const row = [
          log.timestamp,
          log.user_id || '',
          log.action_type,
          log.entity_type || '',
          log.entity_id || '',
          log.ip_address || '',
          log.details ? JSON.stringify(log.details).replace(/,/g, ';') : '',
        ];
        csvRows.push(row.join(','));
      });

      const csvContent = csvRows.join('\n');
      const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
      const link = document.createElement('a');
      const url = URL.createObjectURL(blob);
      link.setAttribute('href', url);
      link.setAttribute('download', 'audit_logs_export.csv');
      link.style.visibility = 'hidden';
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);

      messageApi.success('Audit logs exported successfully');
    } catch (error) {
      messageApi.error('Failed to export audit logs');
    }
  }, [auditLogs, messageApi]);

  const navigateToAdminDashboard = useCallback(() => {
    navigate('/admin/dashboard');
  }, [navigate]);

  const handleDateRangeChange = useCallback((dates: [Dayjs | null, Dayjs | null] | null) => {
    setFilterDateRange(dates);
    setCurrentPage(1);
  }, []);

  const handleUserFilterChange = useCallback((value: string) => {
    setFilterUserId(value);
    setCurrentPage(1);
  }, []);

  const handleActionTypeFilterChange = useCallback((value: string) => {
    setFilterActionType(value);
    setCurrentPage(1);
  }, []);

  const handleEntityTypeFilterChange = useCallback((value: string) => {
    setFilterEntityType(value);
    setCurrentPage(1);
  }, []);

  const handleTableChange = useCallback((pagination: TablePaginationConfig) => {
    if (pagination.current) {
      setCurrentPage(pagination.current);
    }
  }, []);

  const userOptions = useMemo(() => {
    return users.map((user) => ({
      value: user.id,
      label: `${user.first_name} ${user.last_name}`,
    }));
  }, [users]);

  const getActionTypeColor = useCallback((actionType: string): string => {
    const colorMap: Record<string, string> = {
      'Login': 'blue',
      'Logout': 'default',
      'Checkout': 'green',
      'Return': 'cyan',
      'Fine Created': 'orange',
      'Configuration Changed': 'purple',
      'User Created': 'geekblue',
      'User Updated': 'blue',
      'Book Created': 'green',
      'Book Updated': 'lime',
      'Reservation Created': 'gold',
      'Payment Processed': 'magenta',
    };
    return colorMap[actionType] || 'default';
  }, []);

  const columns = useMemo<TableColumnsType<AuditLog>>(() => [
    {
      title: 'Timestamp',
      dataIndex: 'timestamp',
      key: 'timestamp',
      sorter: true,
      width: 180,
      render: (timestamp: string) => new Date(timestamp).toLocaleString(),
    },
    {
      title: 'User',
      dataIndex: 'user_id',
      key: 'user_id',
      width: 180,
      render: (userId: string | null) => {
        if (!userId) return '-';
        const user = users.find((u) => u.id === userId);
        return user ? `${user.first_name} ${user.last_name}` : userId;
      },
    },
    {
      title: 'Action Type',
      dataIndex: 'action_type',
      key: 'action_type',
      width: 160,
      render: (actionType: string) => (
        <Tag color={getActionTypeColor(actionType)}>{actionType}</Tag>
      ),
    },
    {
      title: 'Entity Type',
      dataIndex: 'entity_type',
      key: 'entity_type',
      width: 130,
      render: (entityType: string | null) => entityType || '-',
    },
    {
      title: 'Entity ID',
      dataIndex: 'entity_id',
      key: 'entity_id',
      width: 200,
      ellipsis: true,
      render: (entityId: string | null) => entityId || '-',
    },
    {
      title: 'Details',
      dataIndex: 'details',
      key: 'details',
      width: 100,
      render: (details: Record<string, unknown> | null) => {
        if (!details) return '-';
        return <Typography.Text ellipsis>View</Typography.Text>;
      },
    },
    {
      title: 'IP Address',
      dataIndex: 'ip_address',
      key: 'ip_address',
      width: 140,
      render: (ipAddress: string | null) => ipAddress || '-',
    },
  ], [users, getActionTypeColor]);

  const rootStyle: CSSProperties = {
    minHeight: '100vh',
    height: '100%',
    width: '100%',
    display: 'flex',
    flexDirection: 'column',
    padding: '24px',
    background: '#f5f5f5',
  };

  const headerStyle: CSSProperties = {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '24px',
  };

  const headerLeftStyle: CSSProperties = {
    display: 'flex',
    alignItems: 'center',
    gap: '12px',
  };

  const titleStyle: CSSProperties = {
    margin: 0,
  };

  const filtersCardStyle: CSSProperties = {
    marginBottom: '24px',
  };

  const searchButtonStyle: CSSProperties = {
    marginTop: '30px',
  };

  return (
    <div style={rootStyle}>
      {contextHolder}
      <div style={headerStyle}>
        <div style={headerLeftStyle}>
          <Button
            icon={<ArrowLeftOutlined />}
            type="text"
            onClick={navigateToAdminDashboard}
          >
            Back to Dashboard
          </Button>
          <Typography.Title level={2} style={titleStyle}>
            Audit Logs
          </Typography.Title>
        </div>
        <Button
          type="primary"
          icon={<DownloadOutlined />}
          onClick={exportCsv}
        >
          Export to CSV
        </Button>
      </div>

      <Card title="Filters" style={filtersCardStyle}>
        <Row gutter={[16, 16]}>
          <Col xs={24} sm={12} md={6}>
            <DatePicker.RangePicker
              placeholder={['Start Date', 'End Date']}
              style={{ width: '100%' }}
              value={filterDateRange}
              onChange={handleDateRangeChange}
            />
          </Col>
          <Col xs={24} sm={12} md={6}>
            <Select
              placeholder="All Users"
              allowClear
              showSearch
              optionFilterProp="label"
              style={{ width: '100%' }}
              value={filterUserId || undefined}
              onChange={handleUserFilterChange}
              options={userOptions}
            />
          </Col>
          <Col xs={24} sm={12} md={5}>
            <Select
              placeholder="All Actions"
              allowClear
              style={{ width: '100%' }}
              value={filterActionType || undefined}
              onChange={handleActionTypeFilterChange}
              options={[
                { value: 'Login', label: 'Login' },
                { value: 'Logout', label: 'Logout' },
                { value: 'Checkout', label: 'Checkout' },
                { value: 'Return', label: 'Return' },
                { value: 'Fine Created', label: 'Fine Created' },
                { value: 'Configuration Changed', label: 'Configuration Changed' },
                { value: 'User Created', label: 'User Created' },
                { value: 'User Updated', label: 'User Updated' },
                { value: 'Book Created', label: 'Book Created' },
                { value: 'Book Updated', label: 'Book Updated' },
                { value: 'Reservation Created', label: 'Reservation Created' },
                { value: 'Payment Processed', label: 'Payment Processed' },
              ]}
            />
          </Col>
          <Col xs={24} sm={12} md={5}>
            <Select
              placeholder="All Entities"
              allowClear
              style={{ width: '100%' }}
              value={filterEntityType || undefined}
              onChange={handleEntityTypeFilterChange}
              options={[
                { value: 'User', label: 'User' },
                { value: 'Book', label: 'Book' },
                { value: 'Loan', label: 'Loan' },
                { value: 'Fine', label: 'Fine' },
                { value: 'Payment', label: 'Payment' },
                { value: 'Configuration', label: 'Configuration' },
                { value: 'Reservation', label: 'Reservation' },
                { value: 'Member', label: 'Member' },
                { value: 'BookCopy', label: 'BookCopy' },
              ]}
            />
          </Col>
          <Col xs={24} sm={12} md={2}>
            <Button
              type="primary"
              icon={<SearchOutlined />}
              block
              style={searchButtonStyle}
              onClick={searchAuditLogs}
            >
              Search
            </Button>
          </Col>
        </Row>
      </Card>

      <Card>
        <Table<AuditLog>
          rowKey="id"
          columns={columns}
          dataSource={auditLogs}
          loading={loading}
          pagination={{
            current: currentPage,
            pageSize: 50,
            total: totalRecords,
            showSizeChanger: false,
            showTotal: (total) => `Total ${total} items`,
          }}
          onChange={handleTableChange}
          expandable={{
            expandedRowRender: (record) => {
              if (!record.details) return <p>No details available</p>;
              return (
                <pre style={{ margin: 0 }}>
                  {JSON.stringify(record.details, null, 2)}
                </pre>
              );
            },
          }}
        />
      </Card>
    </div>
  );
}