import React, { useState, useEffect, useCallback } from 'react';
import { Card, Col, Row, message, Table, Button, Input, Form, Space } from 'antd';
import type { TableColumnsType } from 'antd';
import { ReloadOutlined, DeleteOutlined, KeyOutlined, FileTextOutlined, AppstoreOutlined } from '@ant-design/icons';
import {
  listCacheName,
  listCacheKey,
  getCacheValue,
  clearCacheName,
  clearCacheKey,
  clearCacheAll,
} from '../../api/monitor/cache';
import type {
  CacheKeyPayload,
  CacheKeyRecord,
  CacheNamePayload,
  CacheNameRecord,
} from '@/types/api';
import Permission from '@/components/Permission';
import { usePermission } from '@/contexts/PermissionContext';
import ReadonlyAction from '@/components/Permission/ReadonlyAction';
import './cache-list.css';

interface CacheForm {
  cacheName: string;
  cacheKey: string;
  cacheValue: string;
}

const defaultForm: CacheForm = {
  cacheName: '',
  cacheKey: '',
  cacheValue: '',
};

const stringifyValue = (value: unknown): string => {
  if (value === undefined || value === null) {
    return '';
  }
  if (typeof value === 'string') {
    return value;
  }
  try {
    return JSON.stringify(value, null, 2);
  } catch {
    return String(value);
  }
};

const toCacheNameRecord = (item: string | CacheNameRecord): CacheNameRecord => {
  if (typeof item === 'string') {
    return { cacheName: item, remark: `缓存 ${item}` };
  }
  return {
    cacheName: item.cacheName,
    remark: item.remark ?? `缓存 ${item.cacheName}`,
  };
};

const toCacheKeyString = (item: string | CacheKeyRecord): string => {
  return typeof item === 'string' ? item : item.cacheKey;
};

const extractCacheNames = (payload: CacheNamePayload): CacheNameRecord[] => {
  if (!payload) {
    return [];
  }

  if (Array.isArray(payload)) {
    return payload.map((item) => toCacheNameRecord(item));
  }

  if ('cacheNames' in payload && Array.isArray(payload.cacheNames)) {
    return payload.cacheNames.map((item) => toCacheNameRecord(item));
  }

  return [];
};

const extractCacheKeys = (payload: CacheKeyPayload): string[] => {
  if (!payload) {
    return [];
  }

  if (Array.isArray(payload)) {
    return payload.map((item) => toCacheKeyString(item));
  }

  if ('cacheKeys' in payload && Array.isArray(payload.cacheKeys)) {
    return payload.cacheKeys.map((item) => toCacheKeyString(item));
  }

  return [];
};

const CacheListPage: React.FC = () => {
  const { hasPermi } = usePermission();
  const [cacheNames, setCacheNames] = useState<CacheNameRecord[]>([]);
  const [cacheKeys, setCacheKeys] = useState<string[]>([]);
  const [cacheForm, setCacheForm] = useState<CacheForm>(defaultForm);
  const [loading, setLoading] = useState(false);
  const [subLoading, setSubLoading] = useState(false);
  const [nowCacheName, setNowCacheName] = useState('');
  const [tableHeight, setTableHeight] = useState(window.innerHeight - 200);
  const canClearCache = hasPermi('monitor:cache:list');

  const getCacheKeys = useCallback(
    async (cacheName?: string) => {
      const targetCacheName = cacheName ?? nowCacheName;
      if (!targetCacheName) {
        setCacheKeys([]);
        setCacheForm(defaultForm);
        return;
      }

      setSubLoading(true);
      try {
        const response = await listCacheKey(targetCacheName);
        const keys = extractCacheKeys(response);
        setCacheKeys(keys);
        setNowCacheName(targetCacheName);
        setCacheForm({
          cacheName: targetCacheName,
          cacheKey: '',
          cacheValue: '',
        });
      } catch (error: unknown) {
        console.error('Failed to fetch cache keys:', error);
        message.error('获取缓存键名列表失败');
      } finally {
        setSubLoading(false);
      }
    },
    [nowCacheName],
  );

  const getCacheNames = useCallback(async () => {
    setLoading(true);
    try {
      const response = await listCacheName();
      const names = extractCacheNames(response);
      setCacheNames(names);

      if (names.length === 0) {
        setNowCacheName('');
        setCacheKeys([]);
        setCacheForm(defaultForm);
        return;
      }

      const targetCacheName =
        nowCacheName && names.some((item) => item.cacheName === nowCacheName)
          ? nowCacheName
          : names[0].cacheName;

      await getCacheKeys(targetCacheName);
    } catch (error: unknown) {
      console.error('Failed to fetch cache names:', error);
      message.error('获取缓存名称列表失败');
    } finally {
      setLoading(false);
    }
  }, [getCacheKeys, nowCacheName]);

  const handleCacheValue = useCallback(
    async (fullCacheKey: string) => {
      if (!nowCacheName || !fullCacheKey) {
        return;
      }
      try {
        const response = await getCacheValue(nowCacheName, fullCacheKey);
        setCacheForm({
          cacheName: nowCacheName,
          cacheKey: fullCacheKey,
          cacheValue: stringifyValue(response),
        });
      } catch (error: unknown) {
        console.error('Failed to fetch cache value:', error);
        message.error('获取缓存内容失败');
      }
    },
    [nowCacheName],
  );

  useEffect(() => {
    void getCacheNames();
    const handleResize = () => {
      setTableHeight(window.innerHeight - 200);
    };
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, [getCacheNames]);

  const refreshCacheNames = async () => {
    await getCacheNames();
    message.success('刷新缓存列表成功');
  };

  const handleClearCacheName = async (row: CacheNameRecord) => {
    if (!canClearCache) {
      return;
    }
    try {
      await clearCacheName(row.cacheName);
      message.success(`清理缓存名称[${row.cacheName}]成功`);
      await getCacheNames();
    } catch {
      message.error('清理缓存名称失败');
    }
  };

  const refreshCacheKeys = async () => {
    await getCacheKeys();
    message.success('刷新键名列表成功');
  };

  const handleClearCacheKey = async (fullCacheKey: string) => {
    if (!canClearCache) {
      return;
    }
    if (!nowCacheName) {
      return;
    }

    try {
      await clearCacheKey(fullCacheKey);
      message.success(`清理缓存键名[${fullCacheKey}]成功`);
      await getCacheKeys(nowCacheName);
      setCacheForm({ cacheName: nowCacheName, cacheKey: '', cacheValue: '' });
    } catch {
      message.error('清理缓存键名失败');
    }
  };

  const handleClearCacheAll = async () => {
    if (!canClearCache) {
      return;
    }
    try {
      await clearCacheAll();
      message.success('清理全部缓存成功');
      await getCacheNames();
    } catch {
      message.error('清理全部缓存失败');
    }
  };

  const nameFormatter = (cacheName: string) => {
    return cacheName.endsWith(':') ? cacheName.slice(0, -1) : cacheName;
  };

  const keyFormatter = (fullCacheKey: string) => {
    const prefix = nowCacheName.endsWith(':') ? nowCacheName : `${nowCacheName}:`;
    return fullCacheKey.replace(prefix, '');
  };

  const cacheNamesColumns: TableColumnsType<CacheNameRecord> = [
    {
      title: '序号',
      key: 'index',
      width: 60,
      render: (_text, _record, index) => index + 1,
    },
    {
      title: '缓存名称',
      dataIndex: 'cacheName',
      ellipsis: true,
      render: (text) => nameFormatter(String(text ?? '')),
    },
    { title: '备注', dataIndex: 'remark', ellipsis: true },
    {
      title: '操作',
      key: 'operation',
      width: 60,
      render: (_text, record) => (
        <Permission
          permissions="monitor:cache:list"
          fallback={<ReadonlyAction icon={<DeleteOutlined />} danger>清理</ReadonlyAction>}
        >
          <Button type="link" danger icon={<DeleteOutlined />} onClick={() => void handleClearCacheName(record)} />
        </Permission>
      ),
    },
  ];

  const cacheKeysColumns: TableColumnsType<{ key: string; cacheKey: string }> = [
    {
      title: '序号',
      key: 'index',
      width: 60,
      render: (_text, _record, index) => index + 1,
    },
    {
      title: '缓存键名',
      dataIndex: 'cacheKey',
      ellipsis: true,
      render: (text) => keyFormatter(String(text ?? '')),
    },
    {
      title: '操作',
      key: 'operation',
      width: 60,
      render: (_text, record) => (
        <Permission
          permissions="monitor:cache:list"
          fallback={<ReadonlyAction icon={<DeleteOutlined />} danger>清理</ReadonlyAction>}
        >
          <Button
            type="link"
            danger
            icon={<DeleteOutlined />}
            onClick={() => void handleClearCacheKey(record.cacheKey)}
          />
        </Permission>
      ),
    },
  ];

  return (
    <div className="app-container cache-list-container">
      <Row gutter={[16, 16]}>
        <Col span={8}>
          <Card
            title={<Space><AppstoreOutlined /> 缓存列表</Space>}
            extra={<Button type="text" icon={<ReloadOutlined />} onClick={() => void refreshCacheNames()} />}
            style={{ height: tableHeight + 50, overflow: 'auto' }}
          >
            <Table
              columns={cacheNamesColumns}
              dataSource={cacheNames}
              rowKey="cacheName"
              loading={loading}
              pagination={false}
              size="small"
              onRow={(record) => ({
                onClick: () => void getCacheKeys(record.cacheName),
              })}
              scroll={{ y: tableHeight - 60 }}
            />
          </Card>
        </Col>

        <Col span={8}>
          <Card
            title={<Space><KeyOutlined /> 键名列表</Space>}
            extra={
              <Button
                type="text"
                icon={<ReloadOutlined />}
                onClick={() => void refreshCacheKeys()}
                disabled={!nowCacheName}
              />
            }
            style={{ height: tableHeight + 50, overflow: 'auto' }}
          >
            <Table
              columns={cacheKeysColumns}
              dataSource={cacheKeys.map((key) => ({ key, cacheKey: key }))}
              rowKey="key"
              loading={subLoading}
              pagination={false}
              size="small"
              onRow={(record) => ({
                onClick: () => void handleCacheValue(record.cacheKey),
              })}
              scroll={{ y: tableHeight - 60 }}
            />
          </Card>
        </Col>

        <Col span={8}>
          <Card
            title={<Space><FileTextOutlined /> 缓存内容</Space>}
            extra={
              <Permission permissions="monitor:cache:list">
                <Button type="text" danger onClick={() => void handleClearCacheAll()}>清理全部</Button>
              </Permission>
            }
            style={{ height: tableHeight + 50, overflow: 'auto' }}
          >
            <Form layout="vertical" initialValues={cacheForm}>
              <Form.Item label="缓存名称:">
                <Input value={nameFormatter(cacheForm.cacheName)} readOnly />
              </Form.Item>
              <Form.Item label="缓存键名:">
                <Input value={cacheForm.cacheKey} readOnly />
              </Form.Item>
              <Form.Item label="缓存内容:">
                <Input.TextArea value={cacheForm.cacheValue} rows={8} readOnly />
              </Form.Item>
            </Form>
          </Card>
        </Col>
      </Row>
    </div>
  );
};

export default CacheListPage;
