import React, { useEffect, useState } from "react";
import { api } from "../services/api";
import { useAuth } from "../hooks/useAuth";
import { toast } from "react-toastify";
import { ConfirmDialog } from "../components/ConfirmDialog";
import { StatusBadge } from "../components/StatusBadge";
import { Link } from "react-router-dom";
import { Ban, RefreshCw } from "lucide-react";
import { INSTANCE_TYPES, isPresetInstanceType, normalizeInstanceType } from "../lib/instanceTypes";
import { usePageTitle } from "../hooks/usePageTitle";

interface EditUserForm {
  id: number;
  username: string;
  newUsername: string;
  newPassword: string;
  isAdmin: boolean;
  isFounder: boolean;
}

export function Admin() {
  const { user } = useAuth();
  const [tab, setTab] = useState<"users" | "settings" | "previews">("users");
  usePageTitle(`Admin ${tab[0].toUpperCase()}${tab.slice(1)}`);
  const [users, setUsers] = useState<any[]>([]);
  const [settings, setSettings] = useState<any>(null);
  const [previews, setPreviews] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);

  const [newUsername, setNewUsername] = useState("");
  const [newPassword, setNewPassword] = useState("");
  const [editUser, setEditUser] = useState<EditUserForm | null>(null);
  const [deleteConfirm, setDeleteConfirm] = useState<any>(null);
  const [stopConfirm, setStopConfirm] = useState<any>(null);
  const [saving, setSaving] = useState(false);

  const loadUsers = async () => {
    const res = await api.admin.listUsers();
    if (res.ok) setUsers(res.data || []);
  };
  const loadSettings = async () => {
    const res = await api.admin.getSettings();
    if (res.ok) setSettings({ ...res.data, defaultInstanceType: normalizeInstanceType(res.data?.defaultInstanceType) });
  };
  const loadPreviews = async () => {
    const res = await api.admin.listPreviews();
    if (res.ok) setPreviews(res.data || []);
  };

  useEffect(() => {
    if (!user?.isAdmin) return;
    setLoading(true);
    Promise.all([loadUsers(), loadSettings(), loadPreviews()]).finally(() => setLoading(false));
  }, [user]);

  if (!user?.isAdmin) return (
    <div className="text-center py-20">
      <Ban size={48} className="mx-auto mb-4 text-red-500 dark:text-red-400" />
      <h2 className="text-xl font-semibold">Access Denied</h2>
    </div>
  );

  const handleCreateUser = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    const res = await api.admin.createUser(newUsername, newPassword);
    setSaving(false);
    if (res.ok) { toast.success("User created"); setNewUsername(""); setNewPassword(""); loadUsers(); }
    else toast.error(res.message || "Failed to create user");
  };

  const handleDeleteUser = async () => {
    if (!deleteConfirm) return;
    const res = await api.admin.deleteUser(deleteConfirm.id);
    setDeleteConfirm(null);
    if (res.ok) { toast.success("User deleted"); loadUsers(); }
    else toast.error(res.message || "Failed to delete user");
  };

  const handleSaveUser = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!editUser) return;
    setSaving(true);
    const data: any = {};
    if (editUser.newUsername && editUser.newUsername !== editUser.username) data.username = editUser.newUsername;
    if (editUser.newPassword) data.password = editUser.newPassword;
    const res = await api.admin.updateUser(editUser.id, data);
    setSaving(false);
    if (res.ok) { toast.success("User updated"); setEditUser(null); loadUsers(); }
    else toast.error(res.message || "Failed to update user");
  };

  const handleSaveSettings = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    const res = await api.admin.updateSettings(settings);
    setSaving(false);
    if (res.ok) toast.success("Settings saved");
    else toast.error(res.message || "Failed to save settings");
  };

  const handleStopPreview = async () => {
    if (!stopConfirm) return;
    const res = await api.admin.stopPreview(stopConfirm.id);
    setStopConfirm(null);
    if (res.ok) { toast.success("Stop job enqueued"); loadPreviews(); }
    else toast.error(res.message || "Failed to stop preview");
  };

  return (
    <div className="max-w-5xl">
      <ConfirmDialog
        open={!!deleteConfirm}
        title="Delete User"
        message={`Delete user "${deleteConfirm?.username}"? All their data will be removed.`}
        confirmLabel="Delete User"
        onConfirm={handleDeleteUser}
        onCancel={() => setDeleteConfirm(null)}
        danger
      />
      <ConfirmDialog
        open={!!stopConfirm}
        title="Stop Preview"
        message={`Stop preview #${stopConfirm?.id} for ${stopConfirm?.user?.username}?`}
        confirmLabel="Stop"
        onConfirm={handleStopPreview}
        onCancel={() => setStopConfirm(null)}
        danger
      />

      {/* Edit user modal */}
      {editUser && (
        <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
          <div className="bg-white dark:bg-slate-800 rounded-xl shadow-2xl p-6 w-full max-w-sm">
            <h2 className="font-semibold text-lg mb-4">Edit User: {editUser.username}</h2>
            <form onSubmit={handleSaveUser} className="space-y-3">
              <div>
                <label className={labelCls}>Username</label>
                <input type="text" value={editUser.newUsername}
                  onChange={e => setEditUser(u => u ? { ...u, newUsername: e.target.value } : null)}
                  className={inputCls} />
              </div>
              <div>
                <label className={labelCls}>New Password (leave blank to keep current)</label>
                <input type="password" value={editUser.newPassword} placeholder="New password"
                  onChange={e => setEditUser(u => u ? { ...u, newPassword: e.target.value } : null)}
                  className={inputCls} />
              </div>
              <div className="flex gap-3 pt-2">
                <button type="submit" disabled={saving} className={`${btnCls} flex-1`}>
                  {saving ? "Saving..." : "Save Changes"}
                </button>
                <button type="button" onClick={() => setEditUser(null)}
                  className="flex-1 px-4 py-2 text-sm rounded-lg border border-gray-300 dark:border-slate-600 hover:bg-gray-50 dark:hover:bg-slate-700 transition-colors">
                  Cancel
                </button>
              </div>
            </form>
          </div>
        </div>
      )}

      <h1 className="text-2xl font-bold mb-6">Admin Panel</h1>

      <div className="flex gap-2 mb-6 border-b border-gray-200 dark:border-slate-700">
        {(["users", "settings", "previews"] as const).map(t => (
          <button key={t} onClick={() => setTab(t)}
            className={`px-4 py-2 text-sm font-medium capitalize border-b-2 transition-colors ${
              tab === t ? "border-blue-600 text-blue-600 dark:text-blue-400" : "border-transparent text-gray-600 dark:text-slate-400 hover:text-gray-900 dark:hover:text-slate-200"
            }`}>
            {t}
          </button>
        ))}
      </div>

      {tab === "users" && (
        <div className="space-y-6">
          <div className="bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-700 rounded-xl p-5">
            <h2 className="font-semibold mb-4">Create User</h2>
            <form onSubmit={handleCreateUser} className="flex gap-3">
              <input type="text" value={newUsername} onChange={e => setNewUsername(e.target.value)}
                placeholder="Username" className={inputCls} required />
              <input type="password" value={newPassword} onChange={e => setNewPassword(e.target.value)}
                placeholder="Password (min 8 chars)" className={inputCls} required minLength={8} />
              <button type="submit" disabled={saving} className={btnCls}>Create</button>
            </form>
          </div>

          <div className="bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-700 rounded-xl overflow-hidden">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 dark:border-slate-700 text-xs uppercase text-gray-500 dark:text-slate-400">
                  <th className="px-4 py-3 text-left">Username</th>
                  <th className="px-4 py-3 text-left">Role</th>
                  <th className="px-4 py-3 text-left">Created</th>
                  <th className="px-4 py-3 text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                {users.map(u => (
                  <tr key={u.id} className="border-b border-gray-100 dark:border-slate-700 hover:bg-gray-50 dark:hover:bg-slate-700/50">
                    <td className="px-4 py-3 font-medium">
                      {u.username}
                      {u.isFounder && <span className="ml-2 text-xs bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300 px-1.5 py-0.5 rounded-full">Founder</span>}
                    </td>
                    <td className="px-4 py-3">
                      <span className={`text-xs px-2 py-0.5 rounded-full ${u.isAdmin ? "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300" : "bg-gray-100 text-gray-600 dark:bg-slate-700 dark:text-slate-300"}`}>
                        {u.isAdmin ? "Admin" : "User"}
                      </span>
                    </td>
                    <td className="px-4 py-3 text-gray-500 dark:text-slate-400">{new Date(u.createdAt).toLocaleDateString()}</td>
                    <td className="px-4 py-3 text-right">
                      <div className="flex gap-2 justify-end">
                        <button
                          onClick={() => setEditUser({ id: u.id, username: u.username, newUsername: u.username, newPassword: "", isAdmin: u.isAdmin, isFounder: u.isFounder })}
                          className="text-xs text-gray-600 dark:text-slate-300 hover:underline"
                        >
                          Edit
                        </button>
                        {!u.isFounder && u.id !== user.id && (
                          <>
                            <button
                              onClick={async () => {
                                const res = await api.admin.updateUser(u.id, { isAdmin: !u.isAdmin });
                                if (res.ok) { toast.success(`User ${u.isAdmin ? "demoted" : "promoted"}`); loadUsers(); }
                                else toast.error(res.message || "Failed");
                              }}
                              className="text-xs text-blue-600 dark:text-blue-400 hover:underline"
                            >
                              {u.isAdmin ? "Demote" : "Promote"}
                            </button>
                            <button onClick={() => setDeleteConfirm(u)}
                              className="text-xs text-red-600 dark:text-red-400 hover:underline">Delete</button>
                          </>
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {tab === "settings" && settings && (
        <div className="bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-700 rounded-xl p-5">
          <h2 className="font-semibold mb-4">Global Settings</h2>
          <form onSubmit={handleSaveSettings} className="space-y-4">
            <Field label="Default EC2 Instance Type">
              <select
                value={isPresetInstanceType(settings.defaultInstanceType) ? settings.defaultInstanceType : "custom"}
                onChange={e => setSettings((s: any) => ({ ...s, defaultInstanceType: e.target.value === "custom" ? "" : e.target.value }))}
                className={inputCls}
              >
                {INSTANCE_TYPES.map(t => <option key={t.value} value={t.value}>{t.label} - {t.cost}</option>)}
                <option value="custom">Custom...</option>
              </select>
              {!isPresetInstanceType(settings.defaultInstanceType) && (
                <input type="text" value={settings.defaultInstanceType}
                  onChange={e => setSettings((s: any) => ({ ...s, defaultInstanceType: normalizeInstanceType(e.target.value, "") }))}
                  className={`${inputCls} mt-1`} placeholder="Custom instance type" />
              )}
            </Field>
            <Field label="Max Concurrent Instances Per User">
              <input type="number" value={settings.maxConcurrentInstancesPerUser}
                onChange={e => setSettings((s: any) => ({ ...s, maxConcurrentInstancesPerUser: Number(e.target.value) }))}
                className={inputCls} min={1} max={50} />
            </Field>
            <Field label="Webhook Rate Limit (per minute per user)">
              <input type="number" value={settings.webhookRateLimitPerMinute}
                onChange={e => setSettings((s: any) => ({ ...s, webhookRateLimitPerMinute: Number(e.target.value) }))}
                className={inputCls} min={1} />
            </Field>
            <Field label="Log Size Limit (bytes)">
              <input type="number" value={settings.logSizeLimitBytes}
                onChange={e => setSettings((s: any) => ({ ...s, logSizeLimitBytes: Number(e.target.value) }))}
                className={inputCls} min={1024} />
            </Field>
            <Field label="Preview Retention (days)">
              <input type="number" value={settings.previewRetentionDays}
                onChange={e => setSettings((s: any) => ({ ...s, previewRetentionDays: Number(e.target.value) }))}
                className={inputCls} min={1} />
            </Field>
            <Field label="Contact Email (shown in privacy policy)">
              <input type="email" value={settings.contactEmail}
                onChange={e => setSettings((s: any) => ({ ...s, contactEmail: e.target.value }))}
                className={inputCls} placeholder="admin@example.com" />
            </Field>
            <button type="submit" disabled={saving} className={btnCls}>
              {saving ? "Saving..." : "Save Settings"}
            </button>
          </form>
        </div>
      )}

      {tab === "previews" && (
        <div className="bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-700 rounded-xl overflow-hidden">
          <div className="p-4 border-b border-gray-200 dark:border-slate-700 flex items-center justify-between">
            <h2 className="font-semibold">All Previews</h2>
            <button onClick={loadPreviews} className="inline-flex items-center gap-1 text-sm text-blue-600 dark:text-blue-400 hover:underline"><RefreshCw size={14} /> Refresh</button>
          </div>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-200 dark:border-slate-700 text-xs uppercase text-gray-500 dark:text-slate-400">
                  <th className="px-4 py-3 text-left">Repo / PR</th>
                  <th className="px-4 py-3 text-left">User</th>
                  <th className="px-4 py-3 text-left">Status</th>
                  <th className="px-4 py-3 text-left">IP</th>
                  <th className="px-4 py-3 text-left">Created</th>
                  <th className="px-4 py-3 text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                {previews.map(p => (
                  <tr key={p.id} className="border-b border-gray-100 dark:border-slate-700 hover:bg-gray-50 dark:hover:bg-slate-700/50">
                    <td className="px-4 py-3">
                      <p className="text-xs text-gray-500 dark:text-slate-400">{p.repoOwner}/{p.repoName}</p>
                      <Link to={`/previews/${p.id}`} className="font-medium hover:text-blue-600 dark:hover:text-blue-400">PR #{p.prNumber}</Link>
                    </td>
                    <td className="px-4 py-3 text-gray-600 dark:text-slate-300">{p.user?.username}</td>
                    <td className="px-4 py-3"><StatusBadge status={p.status} reason={p.stopReason} /></td>
                    <td className="px-4 py-3">
                      {p.instanceIp ? (
                        <a href={`http://${p.instanceIp}:${p.port}`} target="_blank" rel="noreferrer"
                          className="text-xs font-mono text-blue-600 dark:text-blue-400 hover:underline">
                          {p.instanceIp}:{p.port}
                        </a>
                      ) : "—"}
                    </td>
                    <td className="px-4 py-3 text-gray-500 dark:text-slate-400">{new Date(p.createdAt).toLocaleDateString()}</td>
                    <td className="px-4 py-3 text-right">
                      {p.status !== "STOPPED" && p.status !== "IGNORED" && (
                        <button onClick={() => setStopConfirm(p)}
                          className="text-xs text-red-600 dark:text-red-400 hover:underline">Stop</button>
                      )}
                    </td>
                  </tr>
                ))}
                {previews.length === 0 && (
                  <tr>
                    <td colSpan={6} className="px-4 py-8 text-center text-sm text-gray-500 dark:text-slate-400">No previews yet.</td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </div>
      )}
    </div>
  );
}

function Field({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div>
      <label className="block text-xs font-medium text-gray-600 dark:text-slate-300 mb-1">{label}</label>
      {children}
    </div>
  );
}

const labelCls = "block text-xs font-medium text-gray-600 dark:text-slate-300 mb-1";
const inputCls = "w-full px-3 py-2 text-sm border border-gray-300 dark:border-slate-600 rounded-lg bg-white dark:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-blue-500";
const btnCls = "px-4 py-2 text-sm rounded-lg bg-blue-600 hover:bg-blue-700 text-white font-medium transition-colors disabled:opacity-50";
