import os
import subprocess
import sys
import platform
from DjangoProjectCLI.consts import vue_project_run_message
class VueProjectCLI:
    def __init__(self, project_name):
        self.project_name = project_name
        self.base_dir = os.getcwd()
        self.dependencies = [
            '@mdi/font',
            'axios',
            'pinia',
            'vue',
            'vue-router',
            'vuetify'
        ]
        self.dev_dependencies = [
            '@types/node',
            '@typescript-eslint/eslint-plugin',
            '@typescript-eslint/parser',
            '@vitejs/plugin-vue',
            '@vue/eslint-config-typescript',
            '@vue/test-utils',
            'eslint',
            'eslint-config-prettier',
            'eslint-plugin-vue',
            'prettier',
            'typescript',
            'vite',
            'vitest',
            'vue-tsc'
        ]

    def _verify_node_installation(self):
        is_windows = platform.system() == 'Windows'

        try:
            if not is_windows:
                # On macOS, we need to source NVM and then check
                cmd = 'source ~/.nvm/nvm.sh && nvm --version'
                # Use bash to execute the command
                result = subprocess.run(
                    cmd,
                    shell=True,
                    executable='/bin/bash',
                    check=True,
                    capture_output=True,
                    text=True
                )
            else:
                cmd = 'nvm version'
                result = subprocess.run(
                    cmd,
                    shell=True,
                    check=True,
                    capture_output=True,
                    text=True
                )
            print(f"NVM is installed (version: {result.stdout.strip()})")
            try:
                if is_windows:
                    subprocess.run('nvm install latest', shell=True, check=True)
                    subprocess.run('nvm use node', shell=True, check=True)
                    subprocess.run('npm --version', shell=True, check=True)

                else:
                    # Obtener última versión de Node.js
                    nvm_ls_remote = 'source ~/.nvm/nvm.sh && nvm list'
                    result = subprocess.run(nvm_ls_remote, shell=True, capture_output=True, text=True)
                    print(result)

                    # Instalar y usar la última versión
                    subprocess.run(f'source ~/.nvm/nvm.sh && nvm install node', shell=True, executable='/bin/bash',
                                   check=True)
                    subprocess.run(f'source ~/.nvm/nvm.sh && nvm use node', shell=True, executable='/bin/bash',
                                   check=True)
                    subprocess.run('source ~/.nvm/nvm.sh && npm --version', shell=True, executable='/bin/bash',
                                   check=True)


            except subprocess.CalledProcessError as e:
                print(f"Error configurando Node.js: {str(e)}")
                sys.exit(1)

            return True
        except subprocess.CalledProcessError:
            print("NVM is not installed. Please install NVM using:\n"
                  "curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash")
            return False

    def create_project_structure(self, project_path):
        folders = [
            'src/assets',
            'src/components',
            'src/router',
            'src/stores',
            'src/views',
            'src/utils'
        ]
        for folder in folders:
            os.makedirs(os.path.join(project_path, folder), exist_ok=True)

    def create_config_files(self, project_path,host="localhost"):
        # vite.config.ts
        vite_config = """
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src')
    }
  }
})
        """
        main_config = """
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'

// Vuetify
import "vuetify/styles";
import { createVuetify } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import "@mdi/font/css/materialdesignicons.css";
import { es } from "vuetify/locale";

import App from './App.vue'
import router from './router'

const vuetify = createVuetify({
  components,
  directives,
  locale: {
      locale: "es",
      fallback: "es",
      messages: { es },
  },
  theme: {
      defaultTheme: "light",
      themes: {
          light: {
              colors: {
                  primary: "#4454ff",
              },
          },
      },
  },
});

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(vuetify)

app.mount('#app')
        """

        router_config = """
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView,
    },
    {
      path: '/about',
      name: 'about',
      // route level code-splitting
      // this generates a separate chunk (About.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () => import('../views/AboutView.vue'),
    },
  ],
})

export default router        
        """

        # Creates vite.config.ts file
        with open(os.path.join(project_path, 'vite.config.ts'), 'w') as f:
            f.write(vite_config.strip())

        # Configures router, store and vuetify in main.ts
        src_path = os.path.join(project_path, 'src')
        main_ts_path = os.path.join(src_path, 'main.ts')

        with open(main_ts_path, 'w') as f:
            f.write(main_config.strip())

        # Creates index router file
        router_path = os.path.join(project_path, 'src', 'router')
        os.makedirs(router_path, exist_ok=True)

        with open(os.path.join(router_path, 'index.ts'), 'w') as f:
            f.write(router_config.strip())

        # .env files
        env_development = f"VITE_API_URL=http://{host}:8000"
        env_production = "VITE_API_URL=https://api.production.com"

        with open(os.path.join(project_path, '.env.development'), 'w') as f:
            f.write(env_development)
        with open(os.path.join(project_path, '.env.production'), 'w') as f:
            f.write(env_production)

        # stores/base.ts
        base_store = """
import { defineStore } from 'pinia'

export const useBaseStore = defineStore('base', {
  state: () => ({
    loading: false,
    error: null
  }),
  actions: {
    setLoading(value: boolean) {
      this.loading = value
    },
    setError(error: any) {
      this.error = error
    }
  }
})
        """
        with open(os.path.join(project_path, 'src/stores/base.ts'), 'w') as f:
            f.write(base_store.strip())

    def create_project(self, project_path, https_enabled, host):
        self._verify_node_installation()
        is_windows = platform.system() == 'Windows'

        project_path = os.path.join(project_path, self.project_name)

        print("Creando proyecto Vue + TypeScript...")
        try:
            # Create Vite project
            if is_windows:
                create_cmd = [
                    'npm', 'create', 'vite@latest', self.project_name,
                    '--','--template', 'vue-ts', '--yes'
                ]
            else:
                create_cmd = f'source ~/.nvm/nvm.sh && npm create vite@latest {self.project_name} -- --template vue-ts'

            subprocess.run(
                create_cmd,
                shell=True,
                executable='/bin/bash' if not is_windows else None,
                check=True
            )

            # Change to project directory
            os.chdir(project_path)

            print("Instalando dependencias...")
            # Install dependencies
            if is_windows:
                subprocess.run(['npm', 'install'], shell=True, check=True)
                subprocess.run(['npm', 'install', *self.dependencies], shell=True, check=True)
                subprocess.run(['npm', 'install', '-D', *self.dev_dependencies], shell=True, check=True)
            else:
                subprocess.run(
                    'source ~/.nvm/nvm.sh && npm install',
                    shell=True,
                    executable='/bin/bash',
                    check=True
                )
                subprocess.run(
                    f'source ~/.nvm/nvm.sh && npm install {" ".join(self.dependencies)}',
                    shell=True,
                    executable='/bin/bash',
                    check=True
                )
                subprocess.run(
                    f'source ~/.nvm/nvm.sh && npm install -D {" ".join(self.dev_dependencies)}',
                    shell=True,
                    executable='/bin/bash',
                    check=True
                )

            # Create structure and configurations
            self.create_project_structure(project_path)
            self.create_config_files(project_path, host=host)

            print(f"✅ Proyecto Vue + TypeScript '{self.project_name}' creado exitosamente")
            print(f"Ubicación: {project_path}")
            print("\nPara comenzar:")
            print("1. Muevase al directorio")
            print(f"   cd {project_path}")
            print(vue_project_run_message)

        except subprocess.CalledProcessError as e:
            print(f"❌ Error al crear el proyecto Vue: {str(e)}")
            sys.exit(1)