import { useState, useEffect } from 'react';
import { Plus, Minus } from 'lucide-react';
import { Button, Select, Card, CardBody } from '../../components/ui';
import { Env, AddEvent, RemoveEvent, UpdateEvent } from '../../models/Env';
import { EnvParam } from '../../models/EnvParam';
import { EnvironmentParam } from './EnvironmentParam';

interface EnvironmentProps {
  envs: Env[];
  onChanged: (env: Env) => void;
  onSelected: (envId: number) => void;
  onAdd: (env: Env) => number;
  onRemove: (envId: number) => void;
}

export function Environment({ envs, onChanged, onSelected, onAdd, onRemove }: EnvironmentProps) {
  const [currEnvId, setCurrEnvId] = useState<number>(envs[0]?.id ?? 0);

  // Sync currEnvId when envs changes
  useEffect(() => {
    if (!envs.find(e => e.id === currEnvId)) {
      setCurrEnvId(envs[0]?.id ?? 0);
    }
  }, [envs, currEnvId]);

  const currEnv = envs.find(e => e.id === currEnvId) ?? envs[0];

  function handleParamChanged(event: AddEvent<EnvParam> | RemoveEvent<EnvParam> | UpdateEvent<EnvParam>) {
    let newEnv: Env = currEnv;
    let isChanged = false;

    if (event instanceof RemoveEvent) {
      newEnv = currEnv.delParam(event.payload);
      isChanged = true;
    } else if (event instanceof AddEvent) {
      newEnv = currEnv.addParams(event.payload);
      isChanged = true;
    } else if (event instanceof UpdateEvent) {
      newEnv = currEnv.updateParams(event.payload);
      isChanged = true;
    }

    if (isChanged) {
      onChanged(newEnv);
      setCurrEnvId(newEnv.id ?? 0);
    }
  }

  function handleAddEnv() {
    const name = prompt('Enter new environment name:');
    if (!name || name.trim() === '') return;

    // Calculate next integer ID based on max existing ID
    const maxId = envs.reduce((max, e) => Math.max(max, e.id ?? 0), -1);
    const newId = maxId + 1;

    const newEnv = new Env(newId, name.trim(), [...currEnv.params]);
    const newIdx = onAdd(newEnv);
    setCurrEnvId(newEnv.id ?? 0);
    onSelected(newIdx);
  }

  function handleRemoveEnv() {
    if (currEnv.isDefault()) {
      alert('Cannot remove DEFAULT environment');
      return;
    }
    if (!confirm(`Remove environment "${currEnv.name}"?`)) return;

    const idx = envs.findIndex(x => x.id === currEnv.id);
    if (idx > -1 && currEnv.id !== undefined) {
      onRemove(currEnv.id);
      const newIdx = Math.max(0, idx - 1);
      const newEnv = envs[newIdx];
      if (newEnv?.id !== undefined) {
        setCurrEnvId(newEnv.id);
      }
      onSelected(newIdx);
    }
  }

  const selectOptions = envs.map((x) => ({
    value: x.id ?? 0,
    label: x.name ?? 'Unknown',
  }));

  const paramCtrls = currEnv.params.map((x) => (
    <EnvironmentParam
      key={`${currEnv.id}-${x.id}`}
      param={new EnvParam(x.id, x.name, x.value)}
      onChanged={handleParamChanged}
      isNew={false}
    />
  ));

  return (
    <Card variant="bordered" padding="none" className="h-full">
      <CardBody className="space-y-4">
        {/* Environment Selector */}
        <div className="flex gap-2">
          <div className="flex-1">
            <Select
              label="Environment"
              value={currEnvId}
              options={selectOptions}
              onChange={(e) => {
                const id = Number.parseInt(e.target.value);
                setCurrEnvId(id);
                onSelected(id);
              }}
              id="environments"
            />
          </div>

          <div className="flex flex-col justify-center gap-2 pt-6">
            <div className="flex gap-2">
              <Button
                variant="success"
                size="sm"
                onClick={handleAddEnv}
                title="Add environment"
                icon={Plus}
              />

              <Button
                variant="danger"
                size="sm"
                onClick={handleRemoveEnv}
                title="Remove environment"
                icon={Minus}
                disabled={currEnv.isDefault()}
              />
            </div>
          </div>
        </div>

        {/* Parameters Section */}
        <div>
          <h3 className="text-sm font-semibold text-slate-700 mb-3 uppercase tracking-wide">
            Parameters
          </h3>
          
          <div className="space-y-2">
            {paramCtrls}
            
            <EnvironmentParam
              key={`${currEnv.id}-new`}
              param={new EnvParam(-1, '', '')}
              onChanged={handleParamChanged}
              isNew={true}
            />
          </div>
        </div>
      </CardBody>
    </Card>
  );
}
