import { IconAlertTriangle, IconKey, IconLock, IconSafe, IconShield, IconUser } from '@douyinfe/semi-icons';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { Banner, Button, Card, Input, Spin, Tabs, Tag, Typography } from '@douyinfe/semi-ui';
import { FormEvent, ReactNode, useCallback, useContext, useEffect, useState, createContext } from 'react';
import { api } from '../../api/client';
import { PasswordInput } from '../shared/PasswordInput';
import { clearAccessToken, getAccessToken, PLATFORM_UNAUTHORIZED_EVENT, PlatformSession, setAccessToken } from './session';

const { Title, Text } = Typography;

type AuthContextValue = {
  session: PlatformSession;
  logout: () => void;
};

const AuthContext = createContext<AuthContextValue | null>(null);

const authAssurances = [
  {
    icon: <IconUser />,
    title: '车辆级权限',
    description: '管理员按车牌与菜单精确授权'
  },
  {
    icon: <IconSafe />,
    title: '会话隔离',
    description: '切换账号自动清理当前用户缓存'
  },
  {
    icon: <IconShield />,
    title: '身份可扩展',
    description: '预留统一身份与外部系统接入'
  }
];

function AuthLoadingState() {
  return <main className="v2-auth-screen is-session-loading">
    <Card className="v2-auth-card v2-auth-loading" bodyStyle={{ padding: 0 }} aria-label="正在恢复平台会话">
      <div className="v2-auth-loading-inner">
        <header className="v2-auth-loading-header">
          <img src="/brand-logo.svg" alt="羚牛智能" />
          <Tag color="blue" prefixIcon={<IconSafe />}>安全会话</Tag>
        </header>
        <div className="v2-auth-loading-status" role="status" aria-live="polite">
          <span><Spin size="large" /></span>
          <div>
            <Title heading={4}>正在验证登录状态</Title>
            <Text type="tertiary">正在恢复账号、菜单与车辆权限，完成后会自动进入工作台。</Text>
          </div>
        </div>
        <div className="v2-auth-loading-skeleton" aria-hidden="true"><i /><i /><i /></div>
        <footer><IconLock /><Text type="tertiary" size="small">会话仅保存在当前浏览器，切换账号时会清理用户数据缓存。</Text></footer>
      </div>
    </Card>
  </main>;
}

function AuthErrorMessage({ message }: { message: string }) {
  return <div className="v2-auth-error">
    <Banner
      type="danger"
      bordered
      closeIcon={null}
      icon={<IconAlertTriangle />}
      title="登录未完成"
      description={message}
    />
  </div>;
}

export function usePlatformSession() {
  const value = useContext(AuthContext);
  if (!value) throw new Error('usePlatformSession must be used inside AuthGate');
  return value;
}

export function AuthGate({ children }: { children: ReactNode }) {
  const queryClient = useQueryClient();
  const [tokenVersion, setTokenVersion] = useState(0);
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [draftToken, setDraftToken] = useState('');
  const [legacyMode, setLegacyMode] = useState(false);
  const [attempted, setAttempted] = useState(() => Boolean(getAccessToken()));
  const [loginPending, setLoginPending] = useState(false);
  const [loginError, setLoginError] = useState('');
  const session = useQuery({
    queryKey: ['platform-session', tokenVersion],
    queryFn: ({ signal }) => api.session(signal),
    retry: false,
    staleTime: Infinity
  });
  const clearClientSession = useCallback(() => {
    void queryClient.cancelQueries();
    queryClient.clear();
  }, [queryClient]);
  const finishLogout = useCallback(() => {
    clearAccessToken();
    clearClientSession();
    setPassword('');
    setDraftToken('');
    setAttempted(false);
    setLoginError('');
    setTokenVersion((value) => value + 1);
  }, [clearClientSession]);
  const logout = useCallback(() => {
    void api.logout().catch(() => undefined).finally(finishLogout);
  }, [finishLogout]);
  useEffect(() => {
    window.addEventListener(PLATFORM_UNAUTHORIZED_EVENT, finishLogout);
    return () => window.removeEventListener(PLATFORM_UNAUTHORIZED_EVENT, finishLogout);
  }, [finishLogout]);

  const login = async (event: FormEvent) => {
    event.preventDefault();
    setAttempted(true);
    setLoginError('');
    setLoginPending(true);
    try {
      if (legacyMode) {
        setAccessToken(draftToken);
      } else {
        const result = await api.login({ username: username.trim(), password });
        setAccessToken(result.accessToken);
      }
      clearClientSession();
      setTokenVersion((value) => value + 1);
    } catch (error) {
      clearAccessToken();
      setLoginError(error instanceof Error ? error.message : '登录失败，请稍后重试');
    } finally {
      setLoginPending(false);
    }
  };
  const switchLoginMode = (mode: string) => {
    setLegacyMode(mode === 'token');
    setLoginError('');
  };

  if (session.isPending) {
    return <AuthLoadingState />;
  }
  if (!session.data) {
    const error = loginError || (attempted && session.error ? session.error.message : '');
    return <div className="v2-auth-screen">
      <section className="v2-auth-intro" aria-labelledby="v2-auth-intro-title">
        <header>
          <img src="/brand-logo.svg" alt="羚牛智能" />
          <Tag color="blue" prefixIcon={<IconSafe />}>车辆数据可信入口</Tag>
        </header>
        <Title id="v2-auth-intro-title" heading={1}>让每一辆车的数据<br />清晰、可控、可信</Title>
        <Text>统一查看实时状态、车辆轨迹与里程数据。账号权限由管理员按车辆和功能精确分配。</Text>
        <ul className="v2-auth-assurances" aria-label="平台身份能力">
          {authAssurances.map((item) => <li key={item.title}>
            <span aria-hidden="true">{item.icon}</span>
            <div><strong>{item.title}</strong><small>{item.description}</small></div>
          </li>)}
        </ul>
        <footer><IconLock /><Text>账号、车辆与菜单权限全程隔离</Text></footer>
      </section>
      <Card className="v2-auth-card" bodyStyle={{ padding: 0 }}>
        <form className="v2-auth-form" onSubmit={login} aria-label={legacyMode ? '运维令牌登录' : '平台账号登录'}>
          <header className="v2-auth-form-heading">
            <img className="v2-auth-logo" src="/brand-logo.svg" alt="羚牛智能" />
            <Tag color={legacyMode ? 'amber' : 'blue'} prefixIcon={legacyMode ? <IconKey /> : <IconUser />}>
              {legacyMode ? '受控运维入口' : '账号权限登录'}
            </Tag>
            <Title heading={3}>登录车辆数据中台</Title>
            <Text type="secondary">{legacyMode ? '仅供平台运维使用，输入服务器访问令牌。' : '使用管理员为你开通的账号登录。'}</Text>
          </header>
          <Tabs
            className="v2-auth-mode-tabs"
            activeKey={legacyMode ? 'token' : 'account'}
            onChange={switchLoginMode}
            tabPaneMotion={false}
            type="button"
          >
            <Tabs.TabPane itemKey="account" tab="账号登录" icon={<IconUser aria-hidden="true" />}>
              <div className="v2-auth-fields">
                <label><span>用户名</span><Input autoFocus required={!legacyMode} autoComplete="username" prefix={<IconUser aria-hidden="true" />} value={username} onChange={setUsername} placeholder="请输入用户名" size="large" /></label>
                <label><span>密码</span><PasswordInput aria-label="登录密码" required={!legacyMode} autoComplete="current-password" prefix={<IconLock aria-hidden="true" />} visibilityLabel="登录密码" value={password} onChange={setPassword} placeholder="请输入密码" size="large" /></label>
              </div>
            </Tabs.TabPane>
            <Tabs.TabPane itemKey="token" tab="运维令牌" icon={<IconKey aria-hidden="true" />}>
              <div className="v2-auth-fields">
                <Banner
                  className="v2-auth-token-note"
                  type="warning"
                  bordered
                  closeIcon={null}
                  title="仅限平台运维"
                  description="令牌只保存在当前浏览器会话，关闭或退出后失效。"
                />
                <label><span>运维访问令牌</span><PasswordInput aria-label="运维访问令牌" autoFocus required={legacyMode} autoComplete="off" prefix={<IconKey aria-hidden="true" />} visibilityLabel="运维访问令牌" value={draftToken} onChange={setDraftToken} placeholder="请输入服务器访问令牌" size="large" /></label>
              </div>
            </Tabs.TabPane>
          </Tabs>
          {error ? <AuthErrorMessage message={error} /> : null}
          <Button block htmlType="submit" loading={loginPending} disabled={loginPending || (legacyMode ? !draftToken.trim() : !username.trim() || !password)} theme="solid" type="primary" size="large">
            {loginPending ? '正在登录…' : legacyMode ? '验证令牌并进入' : '登录工作台'}
          </Button>
          <div className="v2-auth-trust-note"><IconLock /><Text type="tertiary" size="small">登录后按账号隔离菜单、车辆和本地缓存</Text></div>
        </form>
      </Card>
    </div>;
  }
  return <AuthContext.Provider value={{ session: session.data, logout }}>{children}</AuthContext.Provider>;
}
