import { writable, get } from "svelte/store";
import { invoke } from "@tauri-apps/api/core";

export type WorkflowPhase = 1 | 2 | 3 | 4;
export type CriterionStatus = "pending" | "pass" | "fail" | "partial";

export interface VerifyCriterion {
  id: string;
  text: string;
  status: CriterionStatus;
}

export interface WorkflowState {
  version: 1;
  currentPhase: WorkflowPhase;
  quickMode: boolean;
  discuss: {
    description: string;
    contextCaptured: boolean;
  };
  plan: {
    tasksApproved: boolean;
  };
  execute: {
    completed: boolean;
  };
  verify: {
    criteria: VerifyCriterion[];
    verificationComplete: boolean;
    report: string;
  };
}

export const WORKFLOW_STATE_FILENAME = "workflow-state.json";

const DEFAULT_STATE: WorkflowState = {
  version: 1,
  currentPhase: 1,
  quickMode: false,
  discuss: { description: "", contextCaptured: false },
  plan: { tasksApproved: false },
  execute: { completed: false },
  verify: { criteria: [], verificationComplete: false, report: "" },
};

// ─── Pure functions (exported for testing) ───────────────────────────────────

export function buildDiscussPrompt(description: string): string {
  return `Please help me clarify and document the following project goal, then write a \`CONTEXT.md\` file in the working directory.

Project description:
${description}

The \`CONTEXT.md\` file should include:

## Goal
A clear, one-paragraph statement of what we are building and why.

## Scope
What is in scope and what is explicitly out of scope.

## Acceptance Criteria
A numbered list of concrete, verifiable criteria that must be met for this project to be considered complete. Each criterion should be specific and testable.

## Key Assumptions
Any assumptions being made about the implementation, environment, or user needs.

## Open Questions
Any questions that need to be resolved before or during development.

Write the file concisely but thoroughly. Focus on information that guides implementation and defines success.`;
}

export function buildVerifyPrompt(criteria: VerifyCriterion[]): string {
  if (criteria.length === 0) {
    return `Please review the project implementation and write a \`VERIFY.md\` file in the working directory with your overall assessment.

Include:
## Summary
Overall pass/fail assessment.

## Findings
What you found when reviewing the implementation.

## Recommendation
Whether the project is ready to ship or what remains to be done.`;
  }

  const criteriaList = criteria.map((c, i) => `${i + 1}. ${c.text}`).join("\n");

  return `Please verify the project implementation against the following acceptance criteria and write a \`VERIFY.md\` file in the working directory.

Acceptance criteria:
${criteriaList}

For each criterion, check whether it is met by examining the codebase and any relevant files. Then write \`VERIFY.md\` with:

## Summary
Overall PASSED / FAILED / PARTIAL status.

## Criterion Results
For each criterion: state whether it PASSES, FAILS, or is PARTIAL, with a brief explanation.

## Findings
Any notable issues, edge cases, or improvements spotted during review.

## Recommendation
Whether the project is ready to ship or what remains to be done.`;
}

export function canAdvancePhase(state: WorkflowState): boolean {
  switch (state.currentPhase) {
    case 1:
      return state.quickMode || state.discuss.contextCaptured;
    case 2:
      return state.plan.tasksApproved;
    case 3:
      return state.execute.completed;
    case 4:
      return state.verify.verificationComplete;
  }
}

export function canGoBack(phase: WorkflowPhase): boolean {
  return phase > 1;
}

export function getPhaseLabel(phase: WorkflowPhase): string {
  switch (phase) {
    case 1:
      return "Discuss";
    case 2:
      return "Plan";
    case 3:
      return "Execute";
    case 4:
      return "Verify";
  }
}

export function generateCriterionId(): string {
  return `criterion-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
}

// ─── Store ────────────────────────────────────────────────────────────────────

function createWorkflowStore() {
  const state = writable<WorkflowState>({ ...DEFAULT_STATE });

  async function loadState(workingDirectory: string): Promise<void> {
    try {
      const path = `${workingDirectory}/${WORKFLOW_STATE_FILENAME}`;
      const content = await invoke<string>("read_file_content", { path });
      const parsed = JSON.parse(content) as WorkflowState;
      state.set(parsed);
    } catch {
      state.set({ ...DEFAULT_STATE });
    }
  }

  async function saveState(workingDirectory: string): Promise<void> {
    try {
      const path = `${workingDirectory}/${WORKFLOW_STATE_FILENAME}`;
      const current = get(state);
      await invoke("write_file_content", { path, content: JSON.stringify(current, null, 2) });
    } catch (error) {
      console.error("Failed to save workflow state:", error);
    }
  }

  function setPhase(phase: WorkflowPhase): void {
    state.update((s) => ({ ...s, currentPhase: phase }));
  }

  function setQuickMode(value: boolean): void {
    state.update((s) => ({ ...s, quickMode: value }));
  }

  function reset(): void {
    state.set({ ...DEFAULT_STATE });
  }

  function setDiscussDescription(text: string): void {
    state.update((s) => ({ ...s, discuss: { ...s.discuss, description: text } }));
  }

  function markContextCaptured(): void {
    state.update((s) => ({ ...s, discuss: { ...s.discuss, contextCaptured: true } }));
  }

  function approvePlan(): void {
    state.update((s) => ({ ...s, plan: { tasksApproved: true } }));
  }

  function completeExecution(): void {
    state.update((s) => ({ ...s, execute: { completed: true } }));
  }

  function addCriterion(text: string): void {
    const criterion: VerifyCriterion = {
      id: generateCriterionId(),
      text,
      status: "pending",
    };
    state.update((s) => ({
      ...s,
      verify: { ...s.verify, criteria: [...s.verify.criteria, criterion] },
    }));
  }

  function removeCriterion(id: string): void {
    state.update((s) => ({
      ...s,
      verify: { ...s.verify, criteria: s.verify.criteria.filter((c) => c.id !== id) },
    }));
  }

  function updateCriterionStatus(id: string, status: CriterionStatus): void {
    state.update((s) => ({
      ...s,
      verify: {
        ...s.verify,
        criteria: s.verify.criteria.map((c) => (c.id === id ? { ...c, status } : c)),
      },
    }));
  }

  function completeVerification(report: string): void {
    state.update((s) => ({
      ...s,
      verify: { ...s.verify, verificationComplete: true, report },
    }));
  }

  return {
    state: { subscribe: state.subscribe },
    loadState,
    saveState,
    setPhase,
    setQuickMode,
    reset,
    setDiscussDescription,
    markContextCaptured,
    approvePlan,
    completeExecution,
    addCriterion,
    removeCriterion,
    updateCriterionStatus,
    completeVerification,
  };
}

export const workflowStore = createWorkflowStore();
