import type { User, Asset, Category, Announcement } from '../types';
import { initializeStorage } from './mock-data';

// Ensure data is seeded in localStorage
initializeStorage();

// Helper delay function to simulate network response
const delay = (ms: number = 300) => new Promise(resolve => setTimeout(resolve, ms));

const getStored = <T>(key: string): T => {
  const data = localStorage.getItem(key);
  return data ? JSON.parse(data) : [] as unknown as T;
};

const setStored = <T>(key: string, data: T): void => {
  localStorage.setItem(key, JSON.stringify(data));
};

export interface ApiResponse<T> {
  data: T;
  status: number;
}

// Custom mock API client resembling Axios
export const apiClient = {
  get: async <T>(url: string, config?: { params?: any }): Promise<ApiResponse<T>> => {
    await delay();
    
    // Clean up url by removing query string if any
    const cleanUrl = url.split('?')[0];

    // Auth endpoints
    if (cleanUrl === '/auth/session') {
      const activeUserEmail = sessionStorage.getItem('t4b_session_email');
      if (!activeUserEmail) {
        throw { status: 401, message: 'Unauthorized' };
      }
      const users = getStored<User[]>('t4b_users');
      const user = users.find(u => u.email === activeUserEmail);
      if (!user) {
        throw { status: 401, message: 'User not found' };
      }
      return { data: user as unknown as T, status: 200 };
    }

    // Asset endpoints
    if (cleanUrl === '/assets') {
      const assets = getStored<Asset[]>('t4b_assets');
      const params = config?.params || {};
      let filtered = [...assets];

      if (params.categoryId && params.categoryId !== 'all') {
        filtered = filtered.filter(a => a.categoryId === params.categoryId);
      }
      if (params.subcategory && params.subcategory !== 'all') {
        filtered = filtered.filter(a => a.subcategory === params.subcategory);
      }
      if (params.search) {
        const q = params.search.toLowerCase();
        filtered = filtered.filter(a => 
          a.title.toLowerCase().includes(q) || 
          a.description.toLowerCase().includes(q) ||
          a.tags.some(t => t.toLowerCase().includes(q))
        );
      }
      // If client is logged in and not admin, only show published assets
      const activeUserEmail = sessionStorage.getItem('t4b_session_email');
      const users = getStored<User[]>('t4b_users');
      const activeUser = users.find(u => u.email === activeUserEmail);
      if (!activeUser || activeUser.role !== 'ADMIN') {
        filtered = filtered.filter(a => a.status === 'published');
      }

      return { data: filtered as unknown as T, status: 200 };
    }

    if (cleanUrl.startsWith('/assets/')) {
      const id = cleanUrl.split('/assets/')[1];
      const assets = getStored<Asset[]>('t4b_assets');
      const asset = assets.find(a => a.id === id);
      if (!asset) {
        throw { status: 404, message: 'Asset not found' };
      }
      return { data: asset as unknown as T, status: 200 };
    }

    // Categories
    if (cleanUrl === '/categories') {
      const categories = getStored<Category[]>('t4b_categories');
      return { data: categories as unknown as T, status: 200 };
    }



    // Announcements
    if (cleanUrl === '/announcements') {
      const announcements = getStored<Announcement[]>('t4b_announcements');
      return { data: announcements as unknown as T, status: 200 };
    }

    // Admin Client Queue
    if (cleanUrl === '/admin/clients') {
      const users = getStored<User[]>('t4b_users');
      // Filter out admins, return only clients
      const clients = users.filter(u => u.role === 'CLIENT');
      return { data: clients as unknown as T, status: 200 };
    }

    throw { status: 404, message: 'Route not found' };
  },

  post: async <T>(url: string, payload: any): Promise<ApiResponse<T>> => {
    await delay();

    if (url === '/auth/login') {
      const { email, password } = payload;
      const users = getStored<User[]>('t4b_users');
      const user = users.find(u => u.email === email);
      
      if (!user || password !== 'password') {
        throw { status: 400, message: 'Invalid email or password' };
      }

      // Login success, return user (MFA verification will occur if required)
      return { data: user as unknown as T, status: 200 };
    }

    if (url === '/auth/register') {
      const { email, companyName, website, sector, companySize } = payload;
      const users = getStored<User[]>('t4b_users');
      if (users.some(u => u.email === email)) {
        throw { status: 400, message: 'Email already registered' };
      }

      const newUser: User = {
        id: `user-${Date.now()}`,
        email,
        role: 'CLIENT',
        companyName: companyName || '',
        website: website || '',
        sector: sector || 'Technology',
        companySize: companySize || '1-10',
        onboardingStatus: 'NOT_STARTED',
        mfaVerified: false,
        createdAt: new Date().toISOString()
      };

      users.push(newUser);
      setStored('t4b_users', users);
      return { data: newUser as unknown as T, status: 201 };
    }

    if (url === '/auth/mfa-verify') {
      const { email, code } = payload;
      const users = getStored<User[]>('t4b_users');
      const index = users.findIndex(u => u.email === email);

      if (index === -1) {
        throw { status: 404, message: 'User not found' };
      }

      if (code !== '123456') {
        throw { status: 400, message: 'Invalid OTP code. Try "123456"' };
      }

      users[index].mfaVerified = true;
      setStored('t4b_users', users);
      sessionStorage.setItem('t4b_session_email', email);

      return { data: users[index] as unknown as T, status: 200 };
    }

    if (url === '/client/onboarding') {
      const activeUserEmail = sessionStorage.getItem('t4b_session_email');
      const users = getStored<User[]>('t4b_users');
      const index = users.findIndex(u => u.email === activeUserEmail);

      if (index === -1) {
        throw { status: 401, message: 'Unauthorized' };
      }

      users[index] = {
        ...users[index],
        ...payload,
        onboardingStatus: 'FORM_COMPLETED'
      };

      setStored('t4b_users', users);
      return { data: users[index] as unknown as T, status: 200 };
    }

    if (url === '/client/nda') {
      const activeUserEmail = sessionStorage.getItem('t4b_session_email');
      const users = getStored<User[]>('t4b_users');
      const index = users.findIndex(u => u.email === activeUserEmail);

      if (index === -1) {
        throw { status: 401, message: 'Unauthorized' };
      }

      users[index].ndaSignature = {
        type: payload.type,
        dataUrl: payload.dataUrl,
        date: new Date().toISOString()
      };
      users[index].onboardingStatus = 'NDA_SIGNED';

      setStored('t4b_users', users);
      return { data: users[index] as unknown as T, status: 200 };
    }

    if (url === '/client/msa') {
      const activeUserEmail = sessionStorage.getItem('t4b_session_email');
      const users = getStored<User[]>('t4b_users');
      const index = users.findIndex(u => u.email === activeUserEmail);

      if (index === -1) {
        throw { status: 401, message: 'Unauthorized' };
      }

      users[index].msaSignature = {
        type: payload.type,
        dataUrl: payload.dataUrl,
        date: new Date().toISOString()
      };
      users[index].onboardingStatus = 'PENDING_APPROVAL';

      setStored('t4b_users', users);
      return { data: users[index] as unknown as T, status: 200 };
    }

    if (url === '/assets/new') {
      const assets = getStored<Asset[]>('t4b_assets');
      const newAsset: Asset = {
        id: `asset-${Date.now()}`,
        title: payload.title,
        description: payload.description,
        categoryId: payload.categoryId,
        subcategory: payload.subcategory,
        tags: payload.tags || [],
        author: payload.author || 'Admin Staff',
        publishDate: new Date().toISOString().split('T')[0],
        thumbnailUrl: payload.thumbnailUrl || 'https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?w=500&auto=format&fit=crop&q=60',
        downloadUrl: payload.downloadUrl || '#',
        githubUrl: payload.githubUrl,
        status: payload.status || 'draft',
        downloadsCount: 0
      };
      assets.push(newAsset);
      setStored('t4b_assets', assets);
      return { data: newAsset as unknown as T, status: 201 };
    }



    throw { status: 404, message: 'Route not found' };
  },

  put: async <T>(url: string, payload: any): Promise<ApiResponse<T>> => {
    await delay();

    if (url === '/auth/profile') {
      const activeUserEmail = sessionStorage.getItem('t4b_session_email');
      const users = getStored<User[]>('t4b_users');
      const index = users.findIndex(u => u.email === activeUserEmail);

      if (index === -1) {
        throw { status: 401, message: 'Unauthorized' };
      }

      const user = users[index];
      if (payload.password) {
        user.passwordHash = 'hashed_new_password';
      }
      if (payload.companyName !== undefined) user.companyName = payload.companyName;
      if (payload.website !== undefined) user.website = payload.website;
      if (payload.sector !== undefined) user.sector = payload.sector;
      if (payload.companySize !== undefined) user.companySize = payload.companySize;
      if (payload.defaultTheme !== undefined) user.defaultTheme = payload.defaultTheme;

      users[index] = user;
      setStored('t4b_users', users);
      return { data: user as unknown as T, status: 200 };
    }

    if (url.startsWith('/admin/clients/')) {
      const clientId = url.split('/admin/clients/')[1];
      const users = getStored<User[]>('t4b_users');
      const index = users.findIndex(u => u.id === clientId);

      if (index === -1) {
        throw { status: 404, message: 'Client not found' };
      }

      users[index].onboardingStatus = payload.status; // 'APPROVED' or 'REJECTED'
      setStored('t4b_users', users);
      return { data: users[index] as unknown as T, status: 200 };
    }

    if (url.startsWith('/assets/')) {
      const id = url.split('/assets/')[1];
      const assets = getStored<Asset[]>('t4b_assets');
      const index = assets.findIndex(a => a.id === id);

      if (index === -1) {
        throw { status: 404, message: 'Asset not found' };
      }

      assets[index] = {
        ...assets[index],
        ...payload
      };

      setStored('t4b_assets', assets);
      return { data: assets[index] as unknown as T, status: 200 };
    }

    throw { status: 404, message: 'Route not found' };
  },

  delete: async <T>(url: string): Promise<ApiResponse<T>> => {
    await delay();

    if (url.startsWith('/assets/')) {
      const id = url.split('/assets/')[1];
      let assets = getStored<Asset[]>('t4b_assets');
      const exists = assets.some(a => a.id === id);

      if (!exists) {
        throw { status: 404, message: 'Asset not found' };
      }

      assets = assets.filter(a => a.id !== id);
      setStored('t4b_assets', assets);
      return { data: { success: true } as unknown as T, status: 200 };
    }

    throw { status: 404, message: 'Route not found' };
  }
};
