import { definePlugin, runWorker } from "@paperclipai/plugin-sdk";
import { LegalApi } from "./legal-api.js";

const plugin = definePlugin({
  async setup(ctx) {
    const config = (await ctx.config.get()) as { legalApiBaseUrl?: string } | null;
    const baseUrl = config?.legalApiBaseUrl || "http://localhost:8085";
    const api = new LegalApi(baseUrl);

    ctx.logger.info("Legal AI plugin starting", { url: baseUrl });

    // ── Tools ──────────────────────────────────────────────────────

    ctx.tools.register(
      "legal_case_list",
      {
        displayName: "רשימת תיקי ערר",
        description:
          "List all appeal cases in the legal system. Returns case number, title, and status (new/in_progress/drafted/reviewed/final).",
        parametersSchema: {
          type: "object",
          properties: {},
        },
      },
      async () => {
        const cases = await api.listCases();
        return {
          content: JSON.stringify(cases, null, 2),
          data: cases,
        };
      },
    );

    ctx.tools.register(
      "legal_case_get",
      {
        displayName: "פרטי תיק ערר",
        description:
          "Get full details of a legal case including documents list. Provide the case number (e.g. 123/24).",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: {
              type: "string",
              description: "Case number (e.g. 123/24)",
            },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const result = await api.getCase(case_number);
        return {
          content: JSON.stringify(result, null, 2),
          data: result,
        };
      },
    );

    ctx.tools.register(
      "legal_case_create",
      {
        displayName: "יצירת תיק ערר",
        description:
          "Create a new appeal case. Case numbers: 1xxx=licensing, 8xxx=betterment levy, 9xxx=compensation. Also creates a linked Paperclip issue.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: {
              type: "string",
              description: "Case number (e.g. 1234/24)",
            },
            title: { type: "string", description: "Case title" },
            appellants: {
              type: "array",
              items: { type: "string" },
              description: "Appellant names",
            },
            respondents: {
              type: "array",
              items: { type: "string" },
              description: "Respondent names",
            },
            subject: { type: "string", description: "Case subject" },
            property_address: {
              type: "string",
              description: "Property address",
            },
            expected_outcome: {
              type: "string",
              enum: [
                "rejection",
                "partial_acceptance",
                "full_acceptance",
                "betterment_levy",
              ],
              description: "Expected outcome type",
            },
          },
          required: ["case_number", "title"],
        },
      },
      async (params, runCtx) => {
        const input = params as {
          case_number: string;
          title: string;
          appellants?: string[];
          respondents?: string[];
          subject?: string;
          property_address?: string;
          expected_outcome?: string;
        };

        // Create case in legal-ai
        const legalCase = await api.createCase(input);

        // Create linked Paperclip issue
        const issue = await ctx.issues.create({
          companyId: runCtx.companyId,
          title: `[ערר ${input.case_number}] ${input.title}`,
          description: `תיק ערר חדש\nנושא: ${input.subject || ""}\nתוצאה צפויה: ${input.expected_outcome || "לא הוגדרה"}`,
        });

        // Store mapping in plugin state
        await ctx.state.set(
          {
            scopeKind: "issue",
            scopeId: issue.id,
            stateKey: "legal-case-number",
          },
          input.case_number,
        );

        await ctx.activity.log({
          companyId: runCtx.companyId,
          message: `נוצר תיק ערר ${input.case_number} וקושר ל-issue ${issue.id}`,
        });

        return {
          content: `Case ${input.case_number} created and linked to Paperclip issue.\n\n${JSON.stringify(legalCase, null, 2)}`,
          data: { legalCase, issueId: issue.id },
        };
      },
    );

    ctx.tools.register(
      "legal_case_update",
      {
        displayName: "עדכון תיק ערר",
        description:
          "Update a legal case's status, title, subject, or expected outcome.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: {
              type: "string",
              description: "Case number (e.g. 123/24)",
            },
            status: {
              type: "string",
              enum: [
                "new",
                "in_progress",
                "drafted",
                "reviewed",
                "final",
              ],
              description: "New case status",
            },
            title: { type: "string" },
            subject: { type: "string" },
            notes: { type: "string" },
            expected_outcome: {
              type: "string",
              enum: [
                "rejection",
                "partial_acceptance",
                "full_acceptance",
                "betterment_levy",
              ],
            },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number, ...updates } = params as {
          case_number: string;
          status?: string;
          title?: string;
          subject?: string;
          notes?: string;
          expected_outcome?: string;
        };
        const result = await api.updateCase(case_number, updates);
        return {
          content: JSON.stringify(result, null, 2),
          data: result,
        };
      },
    );

    ctx.tools.register(
      "legal_case_status",
      {
        displayName: "סטטוס תהליך עבודה",
        description:
          "Get full workflow status for a case: documents processed, chunks created, draft progress, and suggested next steps.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: {
              type: "string",
              description: "Case number (e.g. 123/24)",
            },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const result = await api.getCaseStatus(case_number);
        return {
          content: JSON.stringify(result, null, 2),
          data: result,
        };
      },
    );

    ctx.tools.register(
      "legal_search",
      {
        displayName: "חיפוש תקדימים משפטיים",
        description:
          "Semantic search (RAG) across previous decisions and documents. Query in Hebrew for best results.",
        parametersSchema: {
          type: "object",
          properties: {
            query: {
              type: "string",
              description: "Search query in Hebrew",
            },
            limit: { type: "number", description: "Max results (default 10)" },
            section_type: {
              type: "string",
              description:
                "Filter by section type: facts, legal_analysis, conclusion, ruling",
            },
          },
          required: ["query"],
        },
      },
      async (params) => {
        const { query, limit, section_type } = params as {
          query: string;
          limit?: number;
          section_type?: string;
        };
        const results = await api.search(query, limit || 10, section_type || "");
        return {
          content: JSON.stringify(results, null, 2),
          data: results,
        };
      },
    );

    ctx.tools.register(
      "legal_case_template",
      {
        displayName: "תבנית החלטה",
        description:
          "Get an outcome-aware decision template for a case, with guidance for the 12-block structure.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: {
              type: "string",
              description: "Case number (e.g. 123/24)",
            },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const result = await api.getTemplate(case_number);
        return {
          content: result.template,
          data: result,
        };
      },
    );

    ctx.tools.register(
      "legal_processing_status",
      {
        displayName: "סטטוס עיבוד כללי",
        description:
          "Get overall processing status: total cases, documents, pending processing, chunks, and style corpus entries.",
        parametersSchema: {
          type: "object",
          properties: {},
        },
      },
      async () => {
        const result = await api.getProcessingStatus();
        return {
          content: JSON.stringify(result, null, 2),
          data: result,
        };
      },
    );

    // ── New Tools (Phase 3) ─────────────────────────────────────────

    ctx.tools.register(
      "legal_document_list",
      {
        displayName: "רשימת מסמכים בתיק",
        description: "List all documents in a case with their extraction status.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const docs = await api.listDocuments(case_number);
        return { content: JSON.stringify(docs, null, 2), data: docs };
      },
    );

    ctx.tools.register(
      "legal_set_outcome",
      {
        displayName: "הזנת תוצאת ערר",
        description: "Set the decision outcome (rejection/full_acceptance/partial_acceptance) and optional reasoning from Dafna.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
            outcome: {
              type: "string",
              enum: ["rejection", "full_acceptance", "partial_acceptance"],
              description: "Decision outcome",
            },
            reasoning: { type: "string", description: "Optional reasoning from Dafna" },
          },
          required: ["case_number", "outcome"],
        },
      },
      async (params) => {
        const { case_number, outcome, reasoning } = params as {
          case_number: string;
          outcome: string;
          reasoning?: string;
        };
        const result = await api.setOutcome(case_number, outcome, reasoning);
        return { content: JSON.stringify(result, null, 2), data: result };
      },
    );

    ctx.tools.register(
      "legal_get_claims",
      {
        displayName: "טענות מחולצות",
        description: "Get extracted claims for a case, grouped by party role.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const result = await api.getClaims(case_number);
        return { content: JSON.stringify(result, null, 2), data: result };
      },
    );

    ctx.tools.register(
      "legal_search_case",
      {
        displayName: "חיפוש בתוך תיק",
        description: "Semantic search within a specific case's documents.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
            query: { type: "string", description: "Search query in Hebrew" },
          },
          required: ["case_number", "query"],
        },
      },
      async (params) => {
        const { case_number, query } = params as { case_number: string; query: string };
        const results = await api.searchCase(case_number, query);
        return { content: JSON.stringify(results, null, 2), data: results };
      },
    );

    ctx.tools.register(
      "legal_find_similar",
      {
        displayName: "תקדימים דומים",
        description: "Find similar cases/precedents for a given case.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const results = await api.findSimilarCases(case_number);
        return { content: JSON.stringify(results, null, 2), data: results };
      },
    );

    ctx.tools.register(
      "legal_run_qa",
      {
        displayName: "בדיקת איכות",
        description: "Run QA validation on a drafted decision. Checks: grounding, claims coverage, neutral background, weights.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const result = await api.runQA(case_number);
        return { content: JSON.stringify(result, null, 2), data: result };
      },
    );

    ctx.tools.register(
      "legal_trigger_learning",
      {
        displayName: "הפעלת לולאת למידה",
        description: "Trigger the learning loop — compare draft to final signed version.",
        parametersSchema: {
          type: "object",
          properties: {
            case_number: { type: "string", description: "Case number" },
          },
          required: ["case_number"],
        },
      },
      async (params) => {
        const { case_number } = params as { case_number: string };
        const result = await api.triggerLearning(case_number);
        return { content: JSON.stringify(result, null, 2), data: result };
      },
    );

    ctx.tools.register(
      "legal_style_guide",
      {
        displayName: "מדריך סגנון",
        description: "Get reference to Dafna's writing style guide.",
        parametersSchema: {
          type: "object",
          properties: {},
        },
      },
      async () => {
        const guide = await api.getStyleGuide();
        return { content: guide, data: { reference: guide } };
      },
    );

    // ── Events ─────────────────────────────────────────────────────

    ctx.events.on("issue.created", async (event) => {
      // Auto-link issues with case number in title
      if (!event.companyId || !event.entityId) return;
      const issue = await ctx.issues.get(event.entityId, event.companyId);
      if (!issue) return;

      const match = issue.title.match(/ערר\s+(\d+\/\d+)/);
      if (match) {
        const caseNumber = match[1];
        await ctx.state.set(
          {
            scopeKind: "issue",
            scopeId: issue.id,
            stateKey: "legal-case-number",
          },
          caseNumber,
        );
        ctx.logger.info("Auto-linked issue to legal case", {
          issueId: issue.id,
          caseNumber,
        });
      }
    });

    // ── Jobs ───────────────────────────────────────────────────────

    ctx.jobs.register("sync-case-status", async (job) => {
      ctx.logger.info("Starting case status sync", { runId: job.runId });

      try {
        const cases = await api.listCases();
        const companies = await ctx.companies.list();
        if (!companies.length) return;

        const companyId = companies[0].id;
        const issues = await ctx.issues.list({ companyId });

        for (const legalCase of cases) {
          for (const issue of issues) {
            const linkedCase = await ctx.state.get({
              scopeKind: "issue",
              scopeId: issue.id,
              stateKey: "legal-case-number",
            });

            if (linkedCase === legalCase.case_number) {
              // Map 13 legal-ai statuses to Paperclip issue status
              const statusMap: Record<string, "todo" | "in_progress" | "done"> = {
                new: "todo",
                uploading: "todo",
                processing: "in_progress",
                documents_ready: "in_progress",
                outcome_set: "in_progress",
                brainstorming: "in_progress",
                direction_approved: "in_progress",
                drafting: "in_progress",
                qa_review: "in_progress",
                drafted: "in_progress",
                exported: "in_progress",
                reviewed: "in_progress",
                final: "done",
              };

              const statusLabels: Record<string, string> = {
                new: "תיק חדש",
                uploading: "העלאת מסמכים",
                processing: "עיבוד מסמכים",
                documents_ready: "מסמכים מוכנים — הזן תוצאה",
                outcome_set: "תוצאה הוזנה — נדרש סיעור מוחות",
                brainstorming: "גיבוש כיוון בתהליך",
                direction_approved: "כיוון אושר — מוכן לכתיבה",
                drafting: "כתיבת החלטה בתהליך",
                qa_review: "בדיקת איכות",
                drafted: "טיוטה מוכנה — בדוק ושלח לדפנה",
                exported: "DOCX נוצר — ממתין לדפנה",
                reviewed: "דפנה הגיהה — העלה גרסה סופית",
                final: "גרסה סופית — לולאת למידה",
              };

              const targetStatus = statusMap[legalCase.status];
              const label = statusLabels[legalCase.status] || legalCase.status;

              if (targetStatus && issue.status !== targetStatus) {
                await ctx.issues.update(issue.id, { status: targetStatus }, companyId);
                await ctx.issues.createComment(
                  issue.id,
                  `📋 ${label}`,
                  companyId,
                );
                ctx.logger.info("Synced issue status", {
                  issueId: issue.id,
                  caseNumber: legalCase.case_number,
                  newStatus: targetStatus,
                });
              }
            }
          }
        }

        ctx.logger.info("Case status sync completed", {
          casesChecked: cases.length,
        });
      } catch (err) {
        ctx.logger.error("Case status sync failed", { error: String(err) });
      }
    });

    ctx.logger.info("Legal AI plugin ready");
  },

  async onHealth() {
    return { status: "ok" as const };
  },
});

export default plugin;
runWorker(plugin, import.meta.url);
