import { createSignal, createEffect, Accessor } from 'solid-js';
import { Project, ProjectStatus, ProjectCollaborator, UserRole } from '../auth/types';

const STORAGE_KEY = 'frenocorp_projects';

function loadProjects(): Project[] {
  try {
    const data = localStorage.getItem(STORAGE_KEY);
    return data ? JSON.parse(data) : [];
  } catch {
    return [];
  }
}

function saveProjects(projects: Project[]): void {
  localStorage.setItem(STORAGE_KEY, JSON.stringify(projects));
}

export interface ProjectService {
  projects: Accessor<Project[]>;
  loading: Accessor<boolean>;
  createProject: (name: string, description: string, ownerId: string) => Promise<Project>;
  updateProject: (id: string, updates: Partial<Project>) => Promise<Project>;
  deleteProject: (id: string) => Promise<void>;
  addCollaborator: (projectId: string, userId: string, role: UserRole) => Promise<Project>;
  removeCollaborator: (projectId: string, userId: string) => Promise<Project>;
  archiveProject: (id: string) => Promise<Project>;
}

export function createProjectService(): ProjectService {
  const [projects, setProjects] = createSignal<Project[]>(loadProjects());
  const [loading, setLoading] = createSignal(false);

  createEffect(() => {
    const current = projects();
    saveProjects(current);
  });

  const createProject = async (
    name: string,
    description: string,
    ownerId: string
  ): Promise<Project> => {
    setLoading(true);
    const project: Project = {
      id: generateProjectId(),
      name,
      description,
      ownerId,
      status: 'draft',
      collaborators: [],
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
    };

    setProjects((prev) => [project, ...prev]);
    setLoading(false);
    return project;
  };

  const updateProject = async (
    id: string,
    updates: Partial<Project>
  ): Promise<Project> => {
    setLoading(true);
    let updated: Project | undefined;
    setProjects((prev) =>
      prev.map((p) => {
        if (p.id === id) {
          updated = { ...p, ...updates, updatedAt: new Date().toISOString() };
          return updated;
        }
        return p;
      })
    );
    setLoading(false);
    return updated!;
  };

  const deleteProject = async (id: string): Promise<void> => {
    setLoading(true);
    setProjects((prev) => prev.filter((p) => p.id !== id));
    setLoading(false);
  };

  const addCollaborator = async (
    projectId: string,
    userId: string,
    role: UserRole
  ): Promise<Project> => {
    setLoading(true);
    let updated: Project | undefined;
    setProjects((prev) =>
      prev.map((p) => {
        if (p.id !== projectId) return p;
        const existing = p.collaborators.find((c) => c.userId === userId);
        if (existing) return p;
        updated = {
          ...p,
          collaborators: [
            ...p.collaborators,
            { userId, role, addedAt: new Date().toISOString() },
          ],
          updatedAt: new Date().toISOString(),
        };
        return updated;
      })
    );
    setLoading(false);
    return updated!;
  };

  const removeCollaborator = async (
    projectId: string,
    userId: string
  ): Promise<Project> => {
    setLoading(true);
    let updated: Project | undefined;
    setProjects((prev) =>
      prev.map((p) => {
        if (p.id !== projectId) return p;
        updated = {
          ...p,
          collaborators: p.collaborators.filter((c) => c.userId !== userId),
          updatedAt: new Date().toISOString(),
        };
        return updated;
      })
    );
    setLoading(false);
    return updated!;
  };

  const archiveProject = async (id: string): Promise<Project> => {
    return updateProject(id, { status: 'archived' });
  };

  return {
    projects,
    loading,
    createProject,
    updateProject,
    deleteProject,
    addCollaborator,
    removeCollaborator,
    archiveProject,
  };
}

export function generateProjectId(): string {
  return `proj_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
}

export function useProjectService() {
  return createProjectService();
}
