/*
Copyright (C) 2025 QuantumNous

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

For commercial licensing, please contact support@quantumnous.com
*/

import React from 'react';
import {
  Button,
  Dropdown,
  Space,
  SplitButtonGroup,
  Tag,
  AvatarGroup,
  Avatar,
  Tooltip,
  Progress,
  Switch,
  Input,
  Modal
} from '@douyinfe/semi-ui';
import {
  timestamp2string,
  renderGroup,
  renderQuota,
  getModelCategories,
  showError
} from '../../../helpers';
import {
  IconTreeTriangleDown,
  IconCopy,
  IconEyeOpened,
  IconEyeClosed,
} from '@douyinfe/semi-icons';

// Render functions
function renderTimestamp(timestamp) {
  return <>{timestamp2string(timestamp)}</>;
}

// Render status column with switch and progress bar
const renderStatus = (text, record, manageToken, t) => {
  const enabled = text === 1;
  const handleToggle = (checked) => {
    if (checked) {
      manageToken(record.id, 'enable', record);
    } else {
      manageToken(record.id, 'disable', record);
    }
  };

  let tagColor = 'black';
  let tagText = t('未知状态');
  if (enabled) {
    tagColor = 'green';
    tagText = t('已启用');
  } else if (text === 2) {
    tagColor = 'red';
    tagText = t('已禁用');
  } else if (text === 3) {
    tagColor = 'yellow';
    tagText = t('已过期');
  } else if (text === 4) {
    tagColor = 'grey';
    tagText = t('已耗尽');
  }

  const used = parseInt(record.used_quota) || 0;
  const remain = parseInt(record.remain_quota) || 0;
  const total = used + remain;
  const percent = total > 0 ? (remain / total) * 100 : 0;

  const getProgressColor = (pct) => {
    if (pct === 100) return 'var(--semi-color-success)';
    if (pct <= 10) return 'var(--semi-color-danger)';
    if (pct <= 30) return 'var(--semi-color-warning)';
    return undefined;
  };

  const quotaSuffix = record.unlimited_quota ? (
    <div className='text-xs'>{t('无限额度')}</div>
  ) : (
    <div className='flex flex-col items-end'>
      <span className='text-xs leading-none'>{`${renderQuota(remain)} / ${renderQuota(total)}`}</span>
      <Progress
        percent={percent}
        stroke={getProgressColor(percent)}
        aria-label='quota usage'
        format={() => `${percent.toFixed(0)}%`}
        style={{ width: '100%', marginTop: '1px', marginBottom: 0 }}
      />
    </div>
  );

  const content = (
    <Tag
      color={tagColor}
      shape='circle'
      size='large'
      prefixIcon={
        <Switch
          size='small'
          checked={enabled}
          onChange={handleToggle}
          aria-label='token status switch'
        />
      }
      suffixIcon={quotaSuffix}
    >
      {tagText}
    </Tag>
  );

  const tooltipContent = record.unlimited_quota ? (
    <div className='text-xs'>
      <div>{t('已用额度')}: {renderQuota(used)}</div>
    </div>
  ) : (
    <div className='text-xs'>
      <div>{t('已用额度')}: {renderQuota(used)}</div>
      <div>{t('剩余额度')}: {renderQuota(remain)} ({percent.toFixed(0)}%)</div>
      <div>{t('总额度')}: {renderQuota(total)}</div>
    </div>
  );

  return (
    <Tooltip content={tooltipContent}>
      {content}
    </Tooltip>
  );
};

// Render group column
const renderGroupColumn = (text, t) => {
  if (text === 'auto') {
    return (
      <Tooltip
        content={t('当前分组为 auto，会自动选择最优分组，当一个组不可用时自动降级到下一个组（熔断机制）')}
        position='top'
      >
        <Tag color='white' shape='circle'> {t('智能熔断')} </Tag>
      </Tooltip>
    );
  }
  return renderGroup(text);
};

// Render token key column with show/hide and copy functionality
const renderTokenKey = (text, record, showKeys, setShowKeys, copyText) => {
  const fullKey = 'sk-' + record.key;
  const maskedKey = 'sk-' + record.key.slice(0, 4) + '**********' + record.key.slice(-4);
  const revealed = !!showKeys[record.id];

  return (
    <div className='w-[200px]'>
      <Input
        readOnly
        value={revealed ? fullKey : maskedKey}
        size='small'
        suffix={
          <div className='flex items-center'>
            <Button
              theme='borderless'
              size='small'
              type='tertiary'
              icon={revealed ? <IconEyeClosed /> : <IconEyeOpened />}
              aria-label='toggle token visibility'
              onClick={(e) => {
                e.stopPropagation();
                setShowKeys(prev => ({ ...prev, [record.id]: !revealed }));
              }}
            />
            <Button
              theme='borderless'
              size='small'
              type='tertiary'
              icon={<IconCopy />}
              aria-label='copy token key'
              onClick={async (e) => {
                e.stopPropagation();
                await copyText(fullKey);
              }}
            />
          </div>
        }
      />
    </div>
  );
};

// Render model limits column
const renderModelLimits = (text, record, t) => {
  if (record.model_limits_enabled && text) {
    const models = text.split(',').filter(Boolean);
    const categories = getModelCategories(t);

    const vendorAvatars = [];
    const matchedModels = new Set();
    Object.entries(categories).forEach(([key, category]) => {
      if (key === 'all') return;
      if (!category.icon || !category.filter) return;
      const vendorModels = models.filter((m) => category.filter({ model_name: m }));
      if (vendorModels.length > 0) {
        vendorAvatars.push(
          <Tooltip key={key} content={vendorModels.join(', ')} position='top' showArrow>
            <Avatar size='extra-extra-small' alt={category.label} color='transparent'>
              {category.icon}
            </Avatar>
          </Tooltip>
        );
        vendorModels.forEach((m) => matchedModels.add(m));
      }
    });

    const unmatchedModels = models.filter((m) => !matchedModels.has(m));
    if (unmatchedModels.length > 0) {
      vendorAvatars.push(
        <Tooltip key='unknown' content={unmatchedModels.join(', ')} position='top' showArrow>
          <Avatar size='extra-extra-small' alt='unknown'>
            {t('其他')}
          </Avatar>
        </Tooltip>
      );
    }

    return (
      <AvatarGroup size='extra-extra-small'>
        {vendorAvatars}
      </AvatarGroup>
    );
  } else {
    return (
      <Tag color='white' shape='circle'>
        {t('无限制')}
      </Tag>
    );
  }
};

// Render IP restrictions column
const renderAllowIps = (text, t) => {
  if (!text || text.trim() === '') {
    return (
      <Tag color='white' shape='circle'>
        {t('无限制')}
      </Tag>
    );
  }

  const ips = text
    .split('\n')
    .map((ip) => ip.trim())
    .filter(Boolean);

  const displayIps = ips.slice(0, 1);
  const extraCount = ips.length - displayIps.length;

  const ipTags = displayIps.map((ip, idx) => (
    <Tag key={idx} shape='circle'>
      {ip}
    </Tag>
  ));

  if (extraCount > 0) {
    ipTags.push(
      <Tooltip
        key='extra'
        content={ips.slice(1).join(', ')}
        position='top'
        showArrow
      >
        <Tag shape='circle'>
          {'+' + extraCount}
        </Tag>
      </Tooltip>
    );
  }

  return <Space wrap>{ipTags}</Space>;
};

// Render operations column
const renderOperations = (text, record, onOpenLink, setEditingToken, setShowEdit, manageToken, refresh, t) => {
  let chats = localStorage.getItem('chats');
  let chatsArray = [];
  let shouldUseCustom = true;

  if (shouldUseCustom) {
    try {
      chats = JSON.parse(chats);
      if (Array.isArray(chats)) {
        for (let i = 0; i < chats.length; i++) {
          let chat = {};
          chat.node = 'item';
          for (let key in chats[i]) {
            if (chats[i].hasOwnProperty(key)) {
              chat.key = i;
              chat.name = key;
              chat.onClick = () => {
                onOpenLink(key, chats[i][key], record);
              };
            }
          }
          chatsArray.push(chat);
        }
      }
    } catch (e) {
      console.log(e);
      showError(t('聊天链接配置错误，请联系管理员'));
    }
  }

  return (
    <Space wrap>
      <SplitButtonGroup
        className="overflow-hidden"
        aria-label={t('项目操作按钮组')}
      >
        <Button
          size="small"
          type='tertiary'
          onClick={() => {
            if (chatsArray.length === 0) {
              showError(t('请联系管理员配置聊天链接'));
            } else {
              onOpenLink(
                'default',
                chats[0][Object.keys(chats[0])[0]],
                record,
              );
            }
          }}
        >
          {t('聊天')}
        </Button>
        <Dropdown
          trigger='click'
          position='bottomRight'
          menu={chatsArray}
        >
          <Button
            type='tertiary'
            icon={<IconTreeTriangleDown />}
            size="small"
          ></Button>
        </Dropdown>
      </SplitButtonGroup>

      <Button
        type='tertiary'
        size="small"
        onClick={() => {
          setEditingToken(record);
          setShowEdit(true);
        }}
      >
        {t('编辑')}
      </Button>

      <Button
        type='danger'
        size="small"
        onClick={() => {
          Modal.confirm({
            title: t('确定是否要删除此令牌？'),
            content: t('此修改将不可逆'),
            onOk: () => {
              (async () => {
                await manageToken(record.id, 'delete', record);
                await refresh();
              })();
            },
          });
        }}
      >
        {t('删除')}
      </Button>
    </Space>
  );
};

export const getTokensColumns = ({
  t,
  showKeys,
  setShowKeys,
  copyText,
  manageToken,
  onOpenLink,
  setEditingToken,
  setShowEdit,
  refresh,
}) => {
  return [
    {
      title: t('名称'),
      dataIndex: 'name',
    },
    {
      title: t('状态'),
      dataIndex: 'status',
      key: 'status',
      render: (text, record) => renderStatus(text, record, manageToken, t),
    },
    {
      title: t('分组'),
      dataIndex: 'group',
      key: 'group',
      render: (text) => renderGroupColumn(text, t),
    },
    {
      title: t('密钥'),
      key: 'token_key',
      render: (text, record) => renderTokenKey(text, record, showKeys, setShowKeys, copyText),
    },
    {
      title: t('可用模型'),
      dataIndex: 'model_limits',
      render: (text, record) => renderModelLimits(text, record, t),
    },
    {
      title: t('IP限制'),
      dataIndex: 'allow_ips',
      render: (text) => renderAllowIps(text, t),
    },
    {
      title: t('创建时间'),
      dataIndex: 'created_time',
      render: (text, record, index) => {
        return <div>{renderTimestamp(text)}</div>;
      },
    },
    {
      title: t('过期时间'),
      dataIndex: 'expired_time',
      render: (text, record, index) => {
        return (
          <div>
            {record.expired_time === -1 ? t('永不过期') : renderTimestamp(text)}
          </div>
        );
      },
    },
    {
      title: '',
      dataIndex: 'operate',
      fixed: 'right',
      render: (text, record, index) => renderOperations(
        text,
        record,
        onOpenLink,
        setEditingToken,
        setShowEdit,
        manageToken,
        refresh,
        t
      ),
    },
  ];
}; 