'use client';

import { create } from 'zustand';
import { AdminUser } from '@/types';
import axios from 'axios';

const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000';

function mapIamRole(roles: { key?: string }[]): 'ADMIN' | 'AGENT' | 'SUPERVISOR' {
  const keys = roles.map((r) => r.key ?? '');
  if (keys.some((k) => k.includes('admin') || k === 'super_admin' || k === 'organization_admin')) return 'ADMIN';
  if (keys.some((k) => k.includes('agent'))) return 'AGENT';
  return 'SUPERVISOR';
}

interface AuthState {
  user: AdminUser | null;
  token: string | null;
  refreshToken: string | null;
  isAuthenticated: boolean;
  login: (email: string, password: string) => Promise<void>;
  logout: () => void;
  setUser: (user: AdminUser, token: string) => void;
  initialize: () => void;
  hasPermission: (key: string) => boolean;
}

export const useAuthStore = create<AuthState>((set, get) => ({
  user: null,
  token: null,
  refreshToken: null,
  isAuthenticated: false,

  initialize: () => {
    if (typeof window === 'undefined') return;
    const token = localStorage.getItem('auth_token');
    const userStr = localStorage.getItem('auth_user');
    if (token && userStr) {
      try {
        const user = JSON.parse(userStr) as AdminUser;
        // backfill for sessions stored before permissions were added
        if (!user.permissions) user.permissions = [];
        if (user.isSuperAdmin === undefined) user.isSuperAdmin = false;
        if (user.isOrgAdmin === undefined) user.isOrgAdmin = false;
        set({ user, token, isAuthenticated: true });
      } catch {
        localStorage.removeItem('auth_token');
        localStorage.removeItem('auth_refresh_token');
        localStorage.removeItem('auth_user');
      }
    }
  },

  login: async (email: string, password: string) => {
    // Step 1: IAM login — returns token + refreshToken only
    const loginRes = await axios.post(`${API_URL}/v1/auth/login`, { email, password });
    const loginData = loginRes.data?.data ?? loginRes.data;
    const { token, refreshToken } = loginData;
    if (!token) throw new Error('No token received from server');

    // Step 2: fetch full user from IAM /v1/auth/me — returns session.userInfo
    // employee is an array here (unlike /auth/me which transforms it to a single object via parseToken)
    const meRes = await axios.get(`${API_URL}/v1/auth/me`, {
      headers: { Authorization: `Bearer ${token}` },
    });
    const iamUser = meRes.data?.data ?? meRes.data;

    // Role permissions — flat array in data.permissions
    const rolePerms = (iamUser.permissions ?? []).map((p: any) => String(p.key));
    // Position permissions — employee[] is an array here; positions[].permissions[] merged by IAM
    const employeeArr: any[] = Array.isArray(iamUser.employee) ? iamUser.employee : [];
    const positionPerms = employeeArr.flatMap((emp: any) =>
      (emp.positions ?? []).flatMap((pos: any) =>
        (pos.permissions ?? []).map((p: any) => String(p.key))
      )
    );
    const permissions = Array.from(new Set([...rolePerms, ...positionPerms]));

    const isSuperAdmin = iamUser.isSuperAdmin ?? false;
    const isOrgAdmin = iamUser.isOrganizationAdmin ?? false;

    // Block individual (passenger) accounts — backoffice requires at least one of:
    // super admin, org admin, an employee position, or an explicit permission.
    if (!isSuperAdmin && !isOrgAdmin && employeeArr.length === 0 && permissions.length === 0) {
      throw new Error('ACCESS_DENIED');
    }

    const user: AdminUser = {
      id: iamUser.id,
      email: iamUser.email,
      fullName: iamUser.name?.en ?? iamUser.name?.am ?? iamUser.email,
      role: mapIamRole(iamUser.roles ?? []),
      active: true,
      permissions,
      isSuperAdmin,
      isOrgAdmin,
    };

    localStorage.setItem('auth_token', token);
    localStorage.setItem('auth_user', JSON.stringify(user));
    if (refreshToken) localStorage.setItem('auth_refresh_token', refreshToken);
    // cookie lets middleware detect auth without reading localStorage
    document.cookie = `auth_token=${token}; path=/; SameSite=Lax`;

    set({ user, token, refreshToken: refreshToken ?? null, isAuthenticated: true });
  },

  logout: () => {
    localStorage.removeItem('auth_token');
    localStorage.removeItem('auth_refresh_token');
    localStorage.removeItem('auth_user');
    document.cookie = 'auth_token=; path=/; max-age=0';
    set({ user: null, token: null, refreshToken: null, isAuthenticated: false });
  },

  setUser: (user: AdminUser, token: string) => {
    set({ user, token, isAuthenticated: true });
  },

  hasPermission: (key: string) => {
    const { user } = get();
    if (!user) return false;
    if (user.isSuperAdmin || user.isOrgAdmin) return true;
    return user.permissions.includes(key);
  },
}));
