import { useMemo, useState } from 'preact/hooks';
import { registerModule, type AsukaModuleComponent } from '../../core/modules';
import { getI18n } from '../../core/i18n';
import { useT } from '../../hooks/useT';
import { useAsukaStore } from '../../store/asukaStore';
import { Card, CardContent, CardHeader, CardTitle } from '../core/Card';
import { Field } from '../core/Field';
import { Input } from '../core/Input';
import { Button } from '../core/Button';
import { getEnabledLicenseFeatures, getLicenseFeatureDefinition } from '../../core/license/license.catalog';

type NoticeTone = 'info' | 'success' | 'error';

type NoticeState = {
  tone: NoticeTone;
  message: string;
} | null;

function noticeClass(tone: NoticeTone): string {
  if (tone === 'success') return 'ask-border-emerald-200 ask-bg-emerald-50 ask-text-emerald-700';
  if (tone === 'error') return 'ask-border-rose-200 ask-bg-rose-50 ask-text-rose-700';
  return 'ask-border-border ask-bg-surface2 ask-text-textMuted';
}

function toErrorMessage(error: unknown, fallback: string): string {
  if (error instanceof Error) return error.message || fallback;
  if (typeof error === 'string' && error.trim()) return error.trim();
  return fallback;
}

export const LicenseModule: AsukaModuleComponent = () => {
  const t = useT();
  const designer = useAsukaStore((state: any) => state.designerInstance ?? null);
  const licenseApi = designer?.util?.license;

  const resolvedAt = useAsukaStore((s: any) => s.licenseResolution?.resolvedAt ?? '');
  const currentLicense = useAsukaStore((s: any) => s.license ?? null);
  const plan = currentLicense?.plan ?? 'free';
  const status = currentLicense?.status ?? 'invalid';
  const activeLicenseId = currentLicense?.licenseId ?? '';

  const activationState = licenseApi?.getActivationState?.() ?? {
    hasResolver: false,
    hasHttp: false,
    hasKey: false,
    hasToken: false,
    hasEntitlements: false,
    source: 'none',
    domain: typeof window !== 'undefined' ? window.location.hostname : undefined,
    instanceId: undefined,
  };

  const enabledFeatures = useMemo<string[]>(
    () => {
      void resolvedAt;
      return getEnabledLicenseFeatures(currentLicense).filter(Boolean) as string[];
    },
    [currentLicense, resolvedAt],
  );

  const exportQuota = licenseApi?.getQuota?.('exports');
  const aiQuota = licenseApi?.getQuota?.('aiCredits');

  const [keyInput, setKeyInput] = useState('');
  const [busyAction, setBusyAction] = useState<'activate' | 'refresh' | 'deactivate' | 'reset' | null>(null);
  const [notice, setNotice] = useState<NoticeState>(null);

  const canRemoteActivate = Boolean(activationState.hasResolver || activationState.hasHttp);
  const keyConfigured = activationState.hasKey;
  const statusLabel = t(`license.status.${status}`, status);
  const planLabel = t(`license.plan.${plan}`, plan);

  const runAction = async (action: 'activate' | 'refresh' | 'deactivate' | 'reset', task: () => Promise<void>) => {
    setBusyAction(action);
    try {
      await task();
    } finally {
      setBusyAction(null);
    }
  };

  const handleActivate = async () => {
    if (!licenseApi) return;
    const nextKey = keyInput.trim();
    if (!nextKey && !keyConfigured) {
      setNotice({ tone: 'error', message: t('license.enterKeyFirst', 'Enter a license key before activating premium features.') });
      return;
    }
    await runAction('activate', async () => {
      try {
        const resolution = await licenseApi.activate({ key: nextKey || undefined });
        setKeyInput('');
        setNotice({
          tone: resolution.ok ? 'success' : 'info',
          message: resolution.ok
            ? t('license.activationSuccess', 'License activated successfully.')
            : t('license.activationPartial', 'The license was checked, but premium features are still unavailable with the current response.'),
        });
      } catch (error) {
        setNotice({ tone: 'error', message: toErrorMessage(error, t('license.activationFailed', 'Unable to activate this license right now.')) });
      }
    });
  };

  const handleRefresh = async () => {
    if (!licenseApi) return;
    await runAction('refresh', async () => {
      try {
        await licenseApi.refresh();
        setNotice({ tone: 'success', message: t('license.refreshSuccess', 'License status refreshed.') });
      } catch (error) {
        setNotice({ tone: 'error', message: toErrorMessage(error, t('license.refreshFailed', 'Unable to refresh the license status.')) });
      }
    });
  };

  const handleReset = async () => {
    if (!licenseApi) return;
    await runAction('reset', async () => {
      try {
        await licenseApi.reset({ clearCache: true });
        setKeyInput('');
        setNotice({ tone: 'info', message: t('license.resetSuccess', 'Local activation data cleared. The designer is now using free mode.') });
      } catch (error) {
        setNotice({ tone: 'error', message: toErrorMessage(error, t('license.resetFailed', 'Unable to clear the local activation data.')) });
      }
    });
  };

  const handleDeactivate = async () => {
    if (!licenseApi) return;
    await runAction('deactivate', async () => {
      try {
        const ok = await licenseApi.deactivate();
        if (ok) {
          setKeyInput('');
          setNotice({ tone: 'success', message: t('license.deactivateSuccess', 'License deactivated for this instance.') });
          return;
        }
        setNotice({ tone: 'error', message: t('license.deactivateFailed', 'The current integration cannot deactivate this instance yet.') });
      } catch (error) {
        setNotice({ tone: 'error', message: toErrorMessage(error, t('license.deactivateFailed', 'The current integration cannot deactivate this instance yet.')) });
      }
    });
  };

  return (
    <Card>
      <CardHeader className="ask-flex ask-items-center ask-justify-between ask-gap-2">
        <CardTitle>{t('modules.license', 'License')}</CardTitle>
        <span className="ask-inline-flex ask-items-center ask-rounded-full ask-border ask-border-borderSubtle ask-bg-surface ask-px-2 ask-py-0.5 ask-text-[10px] ask-font-medium ask-text-textMuted">
          {planLabel}
        </span>
      </CardHeader>

      <CardContent className="ask-flex ask-flex-col ask-gap-4">
        <div className="ask-rounded-2xl ask-border ask-border-border ask-bg-surface2 ask-p-3">
          <div className="ask-flex ask-flex-wrap ask-items-start ask-justify-between ask-gap-3">
            <div className="ask-flex ask-flex-col ask-gap-1">
              <span className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.currentLicense', 'Current license')}</span>
              <div className="ask-flex ask-items-center ask-gap-2">
                <span className="ask-text-[13px] ask-font-semibold ask-text-text">{planLabel}</span>
                <span className="ask-inline-flex ask-items-center ask-rounded-full ask-border ask-border-borderSubtle ask-bg-surface ask-px-2 ask-py-0.5 ask-text-[10px] ask-font-medium ask-text-textMuted">{statusLabel}</span>
              </div>
            </div>
            <div className="ask-min-w-[180px] ask-text-right ask-text-[11px] ask-leading-5 ask-text-textMuted">
              <div>{t('license.sourceLabel', 'Source')}: {t(`license.source.${activationState.source}`, activationState.source)}</div>
              {activeLicenseId ? <div>{activeLicenseId}</div> : null}
            </div>
          </div>

          <div className="ask-mt-3 ask-grid ask-grid-cols-1 ask-gap-2 sm:ask-grid-cols-2">
            <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2">
              <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.domainLabel', 'Domain')}</div>
              <div className="ask-mt-1 ask-text-[12px] ask-font-medium ask-text-text">{activationState.domain || '—'}</div>
            </div>
            <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2">
              <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.instanceIdLabel', 'Instance')}</div>
              <div className="ask-mt-1 ask-break-all ask-text-[12px] ask-font-medium ask-text-text">{activationState.instanceId || '—'}</div>
            </div>
          </div>

          {(exportQuota?.limit != null || aiQuota?.limit != null) ? (
            <div className="ask-mt-3 ask-grid ask-grid-cols-1 ask-gap-2 sm:ask-grid-cols-2">
              {exportQuota?.limit != null ? (
                <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2 ask-text-[11px] ask-text-textMuted">
                  <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.exportQuota', 'Export quota')}</div>
                  <div className="ask-mt-1 ask-text-[12px] ask-font-medium ask-text-text">{exportQuota.remaining !== null ? `${exportQuota.remaining} / ${exportQuota.limit}` : `${exportQuota.used ?? 0} / ${exportQuota.limit}`}</div>
                </div>
              ) : null}
              {aiQuota?.limit != null ? (
                <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2 ask-text-[11px] ask-text-textMuted">
                  <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.aiCreditsQuota', 'AI credits')}</div>
                  <div className="ask-mt-1 ask-text-[12px] ask-font-medium ask-text-text">{aiQuota.remaining !== null ? `${aiQuota.remaining} / ${aiQuota.limit}` : `${aiQuota.used ?? 0} / ${aiQuota.limit}`}</div>
                </div>
              ) : null}
            </div>
          ) : null}
        </div>

        <Card className="ask-rounded-2xl">
          <CardHeader className="ask-px-3 ask-pt-3 ask-pb-2">
            <CardTitle>{t('license.activationTitle', 'Activation')}</CardTitle>
          </CardHeader>
          <CardContent className="ask-px-3 ask-pb-3 ask-flex ask-flex-col ask-gap-4">
            <div className="ask-flex ask-flex-col ask-gap-3">
              <div className="ask-text-[11px] ask-leading-5 ask-text-textMuted">
                {canRemoteActivate
                  ? t('license.remoteReady', 'This integration can resolve a license key directly from the client runtime.')
                  : t('license.remoteMissing', 'No remote license resolver is configured yet in this integration. You can still inspect the current status here.')}
              </div>

              <div className="ask-grid ask-grid-cols-1 ask-gap-2 sm:ask-grid-cols-3">
                <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2">
                  <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.resolverLabel', 'Resolver')}</div>
                  <div className="ask-mt-1 ask-text-[12px] ask-font-medium ask-text-text">
                    {activationState.hasHttp || activationState.hasResolver ? t('license.httpReady', 'HTTP ready') : t('license.notConfigured', 'Not configured')}
                  </div>
                </div>
                <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2">
                  <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.keyStatusLabel', 'Key')}</div>
                  <div className="ask-mt-1 ask-text-[12px] ask-font-medium ask-text-text">
                    {keyConfigured ? t('license.configured', 'Configured') : t('license.missing', 'Missing')}
                  </div>
                </div>
                <div className="ask-rounded-xl ask-border ask-border-borderSubtle ask-bg-surface ask-px-3 ask-py-2">
                  <div className="ask-text-[10px] ask-uppercase ask-tracking-[0.12em] ask-text-textMuted">{t('license.tokenStatusLabel', 'Token')}</div>
                  <div className="ask-mt-1 ask-text-[12px] ask-font-medium ask-text-text">
                    {activationState.hasToken ? t('license.available', 'Available') : t('license.missing', 'Missing')}
                  </div>
                </div>
              </div>
            </div>

            {canRemoteActivate ? (
              <Field
                label={t('license.keyLabel', 'License key')}
                required
                hint={keyConfigured
                  ? t('license.keyStored', 'A key is already configured for refresh. Pasting a new one here replaces it for the current session.')
                  : t('license.activationHint', 'Paste your commercial key to unlock the premium runtime on this instance.')}
                right={keyConfigured ? <span className="ask-text-[10px] ask-font-medium ask-text-textMuted">{t('license.storedShort', 'Stored')}</span> : null}
              >
                <Input
                  required
                  aria-required="true"
                  value={keyInput}
                  onInput={(event) => setKeyInput((event.currentTarget as HTMLInputElement).value)}
                  placeholder={t('license.keyPlaceholder', 'ASK-XXXX-XXXX-XXXX')}
                  autoComplete="off"
                  spellcheck={false}
                />
              </Field>
            ) : null}

            <div className="ask-flex ask-flex-wrap ask-gap-2">
              {canRemoteActivate ? (
                <Button variant="primary" size="sm" onClick={handleActivate} disabled={busyAction !== null}>
                  {busyAction === 'activate' ? t('common.loading', 'Loading…') : t('license.activate', 'Activate license')}
                </Button>
              ) : null}
              <Button variant="ghost" size="sm" onClick={handleRefresh} disabled={busyAction !== null || (!keyConfigured && !activationState.hasToken && !activationState.hasEntitlements)}>
                {busyAction === 'refresh' ? t('common.loading', 'Loading…') : t('license.refreshLicense', 'Refresh license')}
              </Button>
              <Button variant="secondary" size="sm" onClick={handleReset} disabled={busyAction !== null}>
                {busyAction === 'reset' ? t('common.loading', 'Loading…') : t('license.useFreeMode', 'Use free mode')}
              </Button>
              <Button variant="danger" size="sm" onClick={handleDeactivate} disabled={busyAction !== null || !canRemoteActivate || !keyConfigured}>
                {busyAction === 'deactivate' ? t('common.loading', 'Loading…') : t('license.deactivateLicense', 'Deactivate instance')}
              </Button>
            </div>
          </CardContent>
        </Card>

        {notice ? (
          <div className={`ask-rounded-2xl ask-border ask-px-3 ask-py-2 ask-text-[11px] ask-leading-5 ${noticeClass(notice.tone)}`}>
            {notice.message}
          </div>
        ) : null}

        <div className="ask-flex ask-flex-col ask-gap-2">
          <span className="ask-text-[11px] ask-font-semibold ask-uppercase ask-tracking-[0.1em] ask-text-textMuted">{t('license.enabledFeaturesTitle', 'Enabled features')}</span>
          {enabledFeatures.length > 0 ? (
            <div className="ask-flex ask-flex-wrap ask-gap-2">
              {enabledFeatures.map((feature: string) => (
                <span key={`${feature}-${resolvedAt}`} className="ask-inline-flex ask-items-center ask-rounded-full ask-border ask-border-borderSubtle ask-bg-surface ask-px-2 ask-py-1 ask-text-[10px] ask-font-medium ask-text-textMuted">
                  {t(`license.features.${feature}.label`, getLicenseFeatureDefinition(feature)?.label ?? feature)}
                </span>
              ))}
            </div>
          ) : (
            <div className="ask-rounded-xl ask-border ask-border-dashed ask-border-border ask-bg-surface2 ask-px-3 ask-py-2 ask-text-[11px] ask-leading-5 ask-text-textMuted">
              {t('license.noPremiumFeatures', 'No premium features are enabled on this instance yet.')}
            </div>
          )}
        </div>
      </CardContent>
    </Card>
  );
};

registerModule({
  id: 'license',
  label: getI18n().t('modules.license', 'License'),
  icon: 'license',
  displayMode: 'floating',
  keepMounted: true,
  supportedEngines: ['fabric', '3d'],
  render: LicenseModule,
});

export default LicenseModule;
