package server

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"regexp"
	"strings"
	"time"

	"odoo-go/pkg/service"
	"odoo-go/pkg/tools"
)

var dbnamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]+$`)

// isSetupNeeded checks if the current database has been initialized.
func (s *Server) isSetupNeeded() bool {
	var count int
	err := s.pool.QueryRow(context.Background(),
		`SELECT COUNT(*) FROM res_company`).Scan(&count)
	return err != nil || count == 0
}

// handleDatabaseManager serves the database manager page.
// Mirrors: odoo/addons/web/controllers/database.py Database.manager()
func (s *Server) handleDatabaseManager(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	w.Write([]byte(databaseManagerHTML))
}

// handleDatabaseCreate processes the database creation form.
// Mirrors: odoo/addons/web/controllers/database.py Database.create()
// Fields match Python Odoo: name, login, password, phone, lang, country_code, demo
func (s *Server) handleDatabaseCreate(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	var params struct {
		MasterPwd   string `json:"master_pwd"`
		Name        string `json:"name"`
		Login       string `json:"login"`
		Password    string `json:"password"`
		Phone       string `json:"phone"`
		Lang        string `json:"lang"`
		CountryCode string `json:"country_code"`
		Demo        bool   `json:"demo"`
	}
	if err := json.NewDecoder(r.Body).Decode(&params); err != nil {
		writeJSON(w, map[string]string{"error": "Invalid request"})
		return
	}

	// Validate
	if params.Login == "" || params.Password == "" {
		writeJSON(w, map[string]string{"error": "Email and password are required"})
		return
	}
	if len(params.Password) < 4 {
		writeJSON(w, map[string]string{"error": "Password must be at least 4 characters"})
		return
	}

	// Default values
	if params.Lang == "" {
		params.Lang = "en_US"
	}
	if params.CountryCode == "" {
		params.CountryCode = "DE"
	}

	// Map country code
	countryName := "Germany"
	phoneCode := "49"
	switch strings.ToUpper(params.CountryCode) {
	case "AT":
		countryName = "Austria"
		phoneCode = "43"
	case "CH":
		countryName = "Switzerland"
		phoneCode = "41"
	case "US":
		countryName = "United States"
		phoneCode = "1"
	case "GB":
		countryName = "United Kingdom"
		phoneCode = "44"
	case "FR":
		countryName = "France"
		phoneCode = "33"
	}

	// Determine chart of accounts from country
	chart := "skr03"
	switch strings.ToUpper(params.CountryCode) {
	case "AT", "CH":
		chart = "skr03" // Use SKR03 for DACH region
	default:
		chart = "skr03"
	}

	// Extract company name from email domain, or use default
	companyName := "My Company"
	if strings.Contains(params.Login, "@") {
		parts := strings.Split(params.Login, "@")
		if len(parts) == 2 {
			domain := parts[1]
			domainParts := strings.Split(domain, ".")
			if len(domainParts) > 0 {
				companyName = strings.Title(domainParts[0])
			}
		}
	}

	log.Printf("setup: creating database for %q (login: %s, country: %s)", companyName, params.Login, params.CountryCode)

	// Hash password
	hashedPw, err := tools.HashPassword(params.Password)
	if err != nil {
		writeJSON(w, map[string]string{"error": fmt.Sprintf("Password error: %v", err)})
		return
	}

	// Seed the database
	setupCfg := service.SetupConfig{
		CompanyName:   companyName,
		CountryCode:   strings.ToUpper(params.CountryCode),
		CountryName:   countryName,
		PhoneCode:     phoneCode,
		Phone:         params.Phone,
		Email:         params.Login,
		Chart:         chart,
		AdminLogin:    params.Login,
		AdminPassword: hashedPw,
		DemoData:      params.Demo,
	}

	if err := service.SeedWithSetup(context.Background(), s.pool, setupCfg); err != nil {
		log.Printf("setup: error: %v", err)
		writeJSON(w, map[string]string{"error": fmt.Sprintf("Database error: %v", err)})
		return
	}

	// Auto-login: create session and return session cookie
	// Mirrors: odoo/addons/web/controllers/database.py line 82-88
	sess := s.sessions.New(1, 1, params.Login)
	http.SetCookie(w, &http.Cookie{
		Name:     "session_id",
		Value:    sess.ID,
		Path:     "/",
		HttpOnly: true,
		SameSite: http.SameSiteLaxMode,
	})

	log.Printf("setup: database initialized, auto-login as %q", params.Login)
	writeJSON(w, map[string]interface{}{
		"status":     "ok",
		"session_id": sess.ID,
		"redirect":   "/odoo",
	})
}

// handleDatabaseList returns the list of databases.
// Mirrors: odoo/addons/web/controllers/database.py Database.list()
func (s *Server) handleDatabaseListJSON(w http.ResponseWriter, r *http.Request) {
	writeJSON(w, []string{s.config.DBName})
}

func writeJSON(w http.ResponseWriter, v interface{}) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(v)
}

// --- Database Manager HTML ---
// Mirrors: odoo/addons/web/static/src/public/database_manager.create_form.qweb.html
var databaseManagerHTML = `<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1"/>
    <title>Odoo — Database Manager</title>
    <style>
        * { box-sizing: border-box; margin: 0; padding: 0; }
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
               background: #f0eeee; display: flex; align-items: center; justify-content: center; min-height: 100vh; }
        .db-manager { background: white; padding: 40px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                      width: 100%; max-width: 480px; }
        .db-manager h1 { color: #71639e; margin-bottom: 6px; font-size: 24px; }
        .db-manager .subtitle { color: #666; margin-bottom: 24px; font-size: 14px; }
        .db-manager label { display: block; margin-bottom: 4px; font-weight: 500; color: #555; font-size: 13px; }
        .db-manager input, .db-manager select {
            width: 100%; padding: 9px 12px; border: 1px solid #ddd; border-radius: 4px;
            font-size: 14px; margin-bottom: 14px; }
        .db-manager input:focus, .db-manager select:focus {
            outline: none; border-color: #71639e; box-shadow: 0 0 0 2px rgba(113,99,158,0.2); }
        .db-manager button { width: 100%; padding: 14px; background: #71639e; color: white; border: none;
                             border-radius: 4px; font-size: 16px; cursor: pointer; margin-top: 16px; }
        .db-manager button:hover { background: #5f5387; }
        .db-manager button:disabled { background: #aaa; cursor: not-allowed; }
        .error { color: #dc3545; margin-bottom: 12px; display: none; text-align: center; font-size: 14px; }
        .check { display: flex; align-items: center; gap: 8px; margin: 8px 0 4px; }
        .check input { width: auto; margin: 0; }
        .check label { margin: 0; }
        .row { display: flex; gap: 12px; }
        .row > div { flex: 1; }
        .progress { display: none; text-align: center; padding: 30px; }
        .progress .spinner { font-size: 36px; animation: spin 1s linear infinite; display: inline-block; }
        @keyframes spin { to { transform: rotate(360deg); } }
        .hint { color: #999; font-size: 12px; margin-top: -10px; margin-bottom: 12px; }
    </style>
</head>
<body>
    <div class="db-manager">
        <h1>Create Database</h1>
        <p class="subtitle">Set up your Odoo database</p>

        <div id="error" class="error"></div>

        <form id="createForm">
            <label for="master_pwd">Master Password</label>
            <input type="password" id="master_pwd" name="master_pwd" value="admin" placeholder="Master password"/>
            <p class="hint">Default: admin</p>

            <label for="login">Email *</label>
            <input type="email" id="login" name="login" required placeholder="admin@example.com"/>

            <label for="password">Password *</label>
            <input type="password" id="password" name="password" required minlength="4" placeholder="Min. 4 characters"/>

            <label for="phone">Phone</label>
            <input type="tel" id="phone" name="phone" placeholder="+49 30 12345678"/>

            <div class="row">
                <div>
                    <label for="lang">Language</label>
                    <select id="lang" name="lang">
                        <option value="en_US">English (US)</option>
                        <option value="de_DE" selected>German / Deutsch</option>
                        <option value="fr_FR">French / Fran&ccedil;ais</option>
                    </select>
                </div>
                <div>
                    <label for="country_code">Country</label>
                    <select id="country_code" name="country_code">
                        <option value="DE" selected>Germany</option>
                        <option value="AT">Austria</option>
                        <option value="CH">Switzerland</option>
                        <option value="US">United States</option>
                        <option value="GB">United Kingdom</option>
                        <option value="FR">France</option>
                    </select>
                </div>
            </div>

            <div class="check">
                <input type="checkbox" id="demo" name="demo" checked/>
                <label for="demo">Load demonstration data</label>
            </div>

            <button type="submit" id="submitBtn">Create Database</button>
        </form>

        <div id="progress" class="progress">
            <div class="spinner">&#10227;</div>
            <p style="margin-top:12px;color:#666;">Creating database...</p>
        </div>
    </div>

    <script>
    document.getElementById('createForm').addEventListener('submit', function(e) {
        e.preventDefault();
        var btn = document.getElementById('submitBtn');
        var form = document.getElementById('createForm');
        var progress = document.getElementById('progress');
        var errorEl = document.getElementById('error');

        btn.disabled = true;
        errorEl.style.display = 'none';

        var data = {
            master_pwd: document.getElementById('master_pwd').value,
            login: document.getElementById('login').value,
            password: document.getElementById('password').value,
            phone: document.getElementById('phone').value,
            lang: document.getElementById('lang').value,
            country_code: document.getElementById('country_code').value,
            demo: document.getElementById('demo').checked
        };

        form.style.display = 'none';
        progress.style.display = 'block';

        fetch('/web/database/create', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(data)
        })
        .then(function(r) { return r.json(); })
        .then(function(result) {
            if (result.error) {
                form.style.display = 'block';
                progress.style.display = 'none';
                errorEl.textContent = result.error;
                errorEl.style.display = 'block';
                btn.disabled = false;
            } else {
                // Auto-login succeeded, redirect to webclient
                window.location.href = result.redirect || '/odoo';
            }
        })
        .catch(function(err) {
            form.style.display = 'block';
            progress.style.display = 'none';
            errorEl.textContent = 'Connection error: ' + err.message;
            errorEl.style.display = 'block';
            btn.disabled = false;
        });
    });
    </script>
</body>
</html>` + fmt.Sprintf("<!-- generated at %s -->", time.Now().Format(time.RFC3339))
