import { create } from 'zustand';
import api from './api';
import { verifyLicenseOffline } from '../services/offlineLicenseVerifier';

export type LicenseStatus =
  | 'unknown'
  | 'active'
  | 'expired'
  | 'invalid'
  | 'missing'
  | 'unsupported';

export type LicenseSource =
  | 'supabase'
  | 'local'
  | 'cache'
  | 'none'
  | 'unknown';

export interface LicenseBootstrapOptions {
  tokenSource?: () => Promise<string | null>;
  publicKeyPem?: string;
}

export interface LicenseState {
  status: LicenseStatus;
  source: LicenseSource;
  payload?: any;
  reason?: string;
  lastChecked: number;
  bootstrap: (opts?: LicenseBootstrapOptions) => Promise<void>;
  clear: () => void;
}

const STORAGE_KEY = 'licenseState';

async function resolvePublicKey(publicKeyPem?: string): Promise<string | null> {
  const envKey = (import.meta as any).env?.VITE_SUPERADMIN_PUBLIC_KEY;
  if (typeof envKey === 'string' && envKey.trim().length > 0) return envKey;
  if (typeof window === 'undefined') {
    return publicKeyPem && publicKeyPem.trim().length > 0 ? publicKeyPem : null;
  }
  try {
    const res = await api.get('/license/public-key');
    const pk = res?.data?.public_key;
    if (typeof pk === 'string' && pk.trim().length > 0) return pk;
  } catch {}

  const rawJwksUrl = (import.meta as any).env?.VITE_SUPERADMIN_JWKS_URL;
  const jwksUrl = (typeof rawJwksUrl === 'string' && rawJwksUrl.trim().length > 0)
    ? rawJwksUrl.trim()
    : '/api/v1/auth/jwks';
  try {
    let data: any;
    if (/^https?:\/\//i.test(jwksUrl)) {
      const res = await fetch(jwksUrl, { credentials: 'omit' });
      if (!res.ok) throw new Error(`JWKS HTTP ${res.status}`);
      data = await res.json();
    } else {
      const res = await api.get(jwksUrl);
      data = res?.data;
    }
    const keys = Array.isArray(data?.keys) ? data.keys : [];
    const jwk = keys[0];
    const pem = jwk?.pubKeyPem || data?.public_key || data?.publicKey || (typeof data === 'string' ? data : null);
    if (typeof pem === 'string' && pem.trim().length > 0) return pem;
  } catch {
    return publicKeyPem && publicKeyPem.trim().length > 0 ? publicKeyPem : null;
  }
  return publicKeyPem && publicKeyPem.trim().length > 0 ? publicKeyPem : null;
}

async function getCurrentLicenseRow(): Promise<{ token: string | null; source: LicenseSource; serverStatus?: LicenseStatus }> {
  try {
    const res = await api.get('/license/current');
    const data: any = res?.data;
    const token = data?.token || data?.signed_license_token || (typeof data === 'string' ? data : null);
    const rawSource = typeof data?.source === 'string' ? data.source : 'unknown';
    const source: LicenseSource =
      rawSource === 'supabase' || rawSource === 'local' || rawSource === 'cache' || rawSource === 'none'
        ? (rawSource as LicenseSource)
        : 'unknown';
    const serverStatus: LicenseStatus | undefined =
      typeof data?.status === 'string' ? (data.status.toLowerCase() as LicenseStatus) : undefined;
    if (typeof token === 'string' && token.trim().length > 0) return { token, source, serverStatus };
  } catch {
    return { token: readStoredToken(), source: 'unknown' };
  }
  return { token: readStoredToken(), source: 'unknown' };
}

async function getCurrentLicenseToken(): Promise<string | null> {
  return (await getCurrentLicenseRow()).token;
}

function readStoredToken(): string | null {
  if (typeof window === 'undefined') return null;
  try {
    const stored = window.localStorage.getItem('licenseToken');
    if (stored && stored.trim().length > 0) return stored;
  } catch {
    return null;
  }
  return null;
}

function mapReason(reason: string | undefined): LicenseStatus {
  switch (reason) {
    case 'EXPIRED':
      return 'expired';
    case 'UNSUPPORTED_ENVIRONMENT':
      return 'unsupported';
    case 'NOT_YET_VALID':
    case 'INVALID_SIGNATURE':
    case 'UNSUPPORTED_ALGORITHM':
    case 'INVALID_FORMAT':
    default:
      return 'invalid';
  }
}

function persist(token: string | null, status: LicenseStatus, payload: any, source: LicenseSource) {
  if (typeof window === 'undefined') return;
  try {
    window.localStorage.setItem(
      STORAGE_KEY,
      JSON.stringify({ token, status, payload, source })
    );
  } catch {
    return;
  }
}

export const useLicenseStore = create<LicenseState>((set) => ({
  status: 'unknown',
  source: 'unknown',
  payload: undefined,
  reason: undefined,
  lastChecked: 0,
  bootstrap: async (opts = {}) => {
    const { tokenSource, publicKeyPem } = opts;
    let token: string | null = null;
    let source: LicenseSource = 'unknown';
    let serverStatus: LicenseStatus | undefined = undefined;
    try {
      if (tokenSource) {
        token = await tokenSource();
      } else {
        const row = await getCurrentLicenseRow();
        token = row.token;
        source = row.source;
        serverStatus = row.serverStatus;
      }
    } catch {
      token = null;
    }
    if (!token) {
      set({
        status: 'missing',
        source,
        payload: undefined,
        reason: undefined,
        lastChecked: Date.now(),
      });
      persist(null, 'missing', undefined, source);
      return;
    }
    const pk = await resolvePublicKey(publicKeyPem);
    if (!pk) {
      const finalStatus = serverStatus === 'active' ? 'active' : 'unsupported';
      set({
        status: finalStatus,
        source,
        payload: undefined,
        reason: finalStatus === 'active' ? undefined : 'NO_PUBLIC_KEY',
        lastChecked: Date.now(),
      });
      persist(token, finalStatus, undefined, source);
      return;
    }
    const result = await verifyLicenseOffline(token, pk);
    const lastChecked = Date.now();
    if (result.isValid) {
      set({
        status: 'active',
        source,
        payload: result.payload,
        reason: undefined,
        lastChecked,
      });
      persist(token, 'active', result.payload, source);
      return;
    }
    const status = mapReason(result.reason);
    set({
      status,
      source,
      payload: result.payload,
      reason: result.reason,
      lastChecked,
    });
    persist(token, status, result.payload, source);
  },
  clear: () => {
    set({
      status: 'unknown',
      source: 'unknown',
      payload: undefined,
      reason: undefined,
      lastChecked: 0,
    });
    if (typeof window !== 'undefined') {
      try {
        window.localStorage.removeItem(STORAGE_KEY);
      } catch {
        return;
      }
    }
  },
}));

export const licenseStore = useLicenseStore;
